Example #1
0
    def test_no_retry_on_non_applicable_statuses(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action in various statuses in which we shouldn't retry
        non_retry_statuses = [
            LIVEACTION_STATUS_REQUESTED,
            LIVEACTION_STATUS_SCHEDULED,
            LIVEACTION_STATUS_DELAYED,
            LIVEACTION_STATUS_CANCELING,
            LIVEACTION_STATUS_CANCELED,
        ]

        action_ref = 'wolfpack.action-1'

        for status in non_retry_statuses:
            liveaction = LiveActionDB(action=action_ref,
                                      parameters={'actionstr': 'foo'})
            live_action_db, execution_db = action_service.request(liveaction)

            live_action_db.status = status
            execution_db.status = status
            LiveAction.add_or_update(live_action_db)
            ActionExecution.add_or_update(execution_db)

            # Simulate policy "apply_after" run
            self.policy.apply_after(target=live_action_db)

        # None of the actions should have been retried
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), len(non_retry_statuses))
        self.assertEqual(len(action_execution_dbs), len(non_retry_statuses))
Example #2
0
 def test_chained_executions(self):
     action_ref = ResourceReference(name='chain', pack='core')
     execution = ActionExecutionDB(action=action_ref.ref)
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED)
     history = ActionExecutionHistory.get(execution__id=str(execution.id),
                                          raise_exception=True)
     action, _ = action_utils.get_action_by_dict({
         'name': action_ref.name,
         'pack': action_ref.pack
     })
     self.assertDictEqual(history.action,
                          vars(ActionAPI.from_model(action)))
     runner = RunnerType.get_by_name(action.runner_type['name'])
     self.assertDictEqual(history.runner,
                          vars(RunnerTypeAPI.from_model(runner)))
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertDictEqual(history.execution,
                          vars(ActionExecutionAPI.from_model(execution)))
     self.assertGreater(len(history.children), 0)
     for child in history.children:
         record = ActionExecutionHistory.get(id=child, raise_exception=True)
         self.assertEqual(record.parent, str(history.id))
         self.assertEqual(record.action['name'], 'local')
         self.assertEqual(record.runner['name'], 'run-local')
Example #3
0
    def test_no_retry_on_workflow_task(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which times out
        live_action_db = LiveActionDB(
            action='wolfpack.action-1',
            parameters={'actionstr': 'foo'},
            context={'parent': {
                'execution_id': 'abcde'
            }})

        live_action_db, execution_db = action_service.request(live_action_db)
        live_action_db = LiveAction.get_by_id(str(live_action_db.id))
        self.assertEqual(live_action_db.status, LIVEACTION_STATUS_REQUESTED)

        # Expire the workflow instance.
        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        live_action_db.context['policies'] = {}
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # Note: There should be no new objects since live action is under the context of a workflow.
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 1)
        self.assertEqual(len(action_execution_dbs), 1)
        self.assertEqual(action_execution_dbs[0].status,
                         LIVEACTION_STATUS_TIMED_OUT)
Example #4
0
    def test_no_retry_on_non_applicable_statuses(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action in various statuses in which we shouldn't retry
        non_retry_statuses = [
            LIVEACTION_STATUS_REQUESTED,
            LIVEACTION_STATUS_SCHEDULED,
            LIVEACTION_STATUS_DELAYED,
            LIVEACTION_STATUS_CANCELING,
            LIVEACTION_STATUS_CANCELED,
        ]

        action_ref = 'wolfpack.action-1'

        for status in non_retry_statuses:
            liveaction = LiveActionDB(action=action_ref, parameters={'actionstr': 'foo'})
            live_action_db, execution_db = action_service.request(liveaction)

            live_action_db.status = status
            execution_db.status = status
            LiveAction.add_or_update(live_action_db)
            ActionExecution.add_or_update(execution_db)

            # Simulate policy "apply_after" run
            self.policy.apply_after(target=live_action_db)

        # None of the actions should have been retried
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), len(non_retry_statuses))
        self.assertEqual(len(action_execution_dbs), len(non_retry_statuses))
Example #5
0
 def test_basic_execution(self):
     action_ref = ResourceReference(name='local', pack='core')
     execution = ActionExecutionDB(action=action_ref.ref,
                                   parameters={'cmd': 'uname -a'})
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED)
     history = ActionExecutionHistory.get(execution__id=str(execution.id),
                                          raise_exception=True)
     self.assertDictEqual(history.trigger, {})
     self.assertDictEqual(history.trigger_type, {})
     self.assertDictEqual(history.trigger_instance, {})
     self.assertDictEqual(history.rule, {})
     action, _ = action_utils.get_action_by_dict({
         'name': action_ref.name,
         'pack': action_ref.pack
     })
     self.assertDictEqual(history.action,
                          vars(ActionAPI.from_model(action)))
     runner = RunnerType.get_by_name(action.runner_type['name'])
     self.assertDictEqual(history.runner,
                          vars(RunnerTypeAPI.from_model(runner)))
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertDictEqual(history.execution,
                          vars(ActionExecutionAPI.from_model(execution)))
Example #6
0
    def test_retry_on_timeout_max_retries_reached(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which times out
        liveaction = LiveActionDB(action='wolfpack.action-1',
                                  parameters={'actionstr': 'foo'})
        live_action_db, execution_db = action_service.request(liveaction)

        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        live_action_db.context['policies'] = {}
        live_action_db.context['policies']['retry'] = {'retry_count': 2}
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # Note: There should be no new objects since max retries has been reached
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 1)
        self.assertEqual(len(action_execution_dbs), 1)
        self.assertEqual(action_execution_dbs[0].status,
                         LIVEACTION_STATUS_TIMED_OUT)
Example #7
0
    def test_retry_on_timeout_max_retries_reached(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which times out
        liveaction = LiveActionDB(action='wolfpack.action-1', parameters={'actionstr': 'foo'})
        live_action_db, execution_db = action_service.request(liveaction)

        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        live_action_db.context['policies'] = {}
        live_action_db.context['policies']['retry'] = {'retry_count': 2}
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # Note: There should be no new objects since max retries has been reached
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 1)
        self.assertEqual(len(action_execution_dbs), 1)
        self.assertEqual(action_execution_dbs[0].status, LIVEACTION_STATUS_TIMED_OUT)
Example #8
0
    def test_retry_on_timeout_no_retry_since_no_timeout_reached(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which succeeds
        liveaction = LiveActionDB(action='wolfpack.action-1',
                                  parameters={'actionstr': 'foo'})
        live_action_db, execution_db = action_service.request(liveaction)

        live_action_db.status = LIVEACTION_STATUS_SUCCEEDED
        execution_db.status = LIVEACTION_STATUS_SUCCEEDED
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should only be 1 object since the action didn't timeout and therefore it wasn't
        # retried
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 1)
        self.assertEqual(len(action_execution_dbs), 1)
        self.assertEqual(action_execution_dbs[0].status,
                         LIVEACTION_STATUS_SUCCEEDED)
Example #9
0
    def test_no_retry_on_workflow_task(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which times out
        live_action_db = LiveActionDB(
            action='wolfpack.action-1',
            parameters={'actionstr': 'foo'},
            context={'parent': {'execution_id': 'abcde'}}
        )

        live_action_db, execution_db = action_service.request(live_action_db)
        live_action_db = LiveAction.get_by_id(str(live_action_db.id))
        self.assertEqual(live_action_db.status, LIVEACTION_STATUS_REQUESTED)

        # Expire the workflow instance.
        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        live_action_db.context['policies'] = {}
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # Note: There should be no new objects since live action is under the context of a workflow.
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 1)
        self.assertEqual(len(action_execution_dbs), 1)
        self.assertEqual(action_execution_dbs[0].status, LIVEACTION_STATUS_TIMED_OUT)
Example #10
0
    def test_retry_on_timeout_first_retry_is_successful(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which times out
        liveaction = LiveActionDB(action="wolfpack.action-1",
                                  parameters={"actionstr": "foo"})
        live_action_db, execution_db = action_service.request(liveaction)

        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should be two objects - original execution and retried execution
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 2)
        self.assertEqual(len(action_execution_dbs), 2)
        self.assertEqual(action_execution_dbs[0].status,
                         LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(action_execution_dbs[1].status,
                         LIVEACTION_STATUS_REQUESTED)

        # Verify retried execution contains policy related context
        original_liveaction_id = action_execution_dbs[0].liveaction["id"]

        context = action_execution_dbs[1].context
        self.assertIn("policies", context)
        self.assertEqual(context["policies"]["retry"]["retry_count"], 1)
        self.assertEqual(context["policies"]["retry"]["applied_policy"],
                         "test_policy")
        self.assertEqual(
            context["policies"]["retry"]["retried_liveaction_id"],
            original_liveaction_id,
        )

        # Simulate success of second action so no it shouldn't be retried anymore
        live_action_db = live_action_dbs[1]
        live_action_db.status = LIVEACTION_STATUS_SUCCEEDED
        LiveAction.add_or_update(live_action_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should be no new object since action succeeds so no retry was attempted
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 2)
        self.assertEqual(len(action_execution_dbs), 2)
        self.assertEqual(live_action_dbs[0].status,
                         LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(live_action_dbs[1].status,
                         LIVEACTION_STATUS_SUCCEEDED)
Example #11
0
    def test_triggered_execution(self):
        docs = {
            'trigger_type':
            copy.deepcopy(fixture.ARTIFACTS['trigger_type']),
            'trigger':
            copy.deepcopy(fixture.ARTIFACTS['trigger']),
            'rule':
            copy.deepcopy(fixture.ARTIFACTS['rule']),
            'trigger_instance':
            copy.deepcopy(fixture.ARTIFACTS['trigger_instance'])
        }

        # Trigger an action execution.
        trigger_type = TriggerType.add_or_update(
            TriggerTypeAPI.to_model(TriggerTypeAPI(**docs['trigger_type'])))
        trigger = Trigger.add_or_update(
            TriggerAPI.to_model(TriggerAPI(**docs['trigger'])))
        rule = RuleAPI.to_model(RuleAPI(**docs['rule']))
        rule.trigger = reference.get_str_resource_ref_from_model(trigger)
        rule = Rule.add_or_update(rule)
        trigger_instance = TriggerInstance.add_or_update(
            TriggerInstanceAPI.to_model(
                TriggerInstanceAPI(**docs['trigger_instance'])))
        enforcer = RuleEnforcer(trigger_instance, rule)
        enforcer.enforce()

        # Wait for the action execution to complete and then confirm outcome.
        execution = ActionExecution.get(
            context__trigger_instance__id=str(trigger_instance.id))
        self.assertIsNotNone(execution)
        execution = ActionExecution.get_by_id(str(execution.id))
        self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED)
        history = ActionExecutionHistory.get(execution__id=str(execution.id),
                                             raise_exception=True)
        self.assertDictEqual(history.trigger,
                             vars(TriggerAPI.from_model(trigger)))
        self.assertDictEqual(history.trigger_type,
                             vars(TriggerTypeAPI.from_model(trigger_type)))
        self.assertDictEqual(
            history.trigger_instance,
            vars(TriggerInstanceAPI.from_model(trigger_instance)))
        self.assertDictEqual(history.rule, vars(RuleAPI.from_model(rule)))
        action_ref = ResourceReference.from_string_reference(
            ref=execution.action)
        action, _ = action_utils.get_action_by_dict({
            'name': action_ref.name,
            'pack': action_ref.pack
        })
        self.assertDictEqual(history.action,
                             vars(ActionAPI.from_model(action)))
        runner = RunnerType.get_by_name(action.runner_type['name'])
        self.assertDictEqual(history.runner,
                             vars(RunnerTypeAPI.from_model(runner)))
        execution = ActionExecution.get_by_id(str(execution.id))
        self.assertDictEqual(history.execution,
                             vars(ActionExecutionAPI.from_model(execution)))
 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)
 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')
 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)
    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')
Example #16
0
 def test_bootstrap(self):
     tracker = results_tracker.ResultsTracker()
     tracker._bootstrap()
     eventlet.sleep(0.2)
     exec_id = str(ResultsTrackerTests.states['state1.json'].execution_id)
     exec_db = ActionExecution.get_by_id(exec_id)
     self.assertTrue(exec_db.result['called_with'][exec_id] is not None,
                     exec_db.result)
     exec_id = str(ResultsTrackerTests.states['state2.json'].execution_id)
     exec_db = ActionExecution.get_by_id(exec_id)
     self.assertTrue(exec_db.result['called_with'][exec_id] is not None,
                     exec_db.result)
     tracker.shutdown()
 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')
Example #18
0
 def put(self, id, actionexecution):
     try:
         actionexec_db = ActionExecution.get_by_id(id)
     except:
         msg = 'ActionExecution by id: %s not found.' % id
         pecan.abort(http_client, msg)
     new_actionexec_db = ActionExecutionAPI.to_model(actionexecution)
     if actionexec_db.status != new_actionexec_db.status:
         actionexec_db.status = new_actionexec_db.status
     if actionexec_db.result != new_actionexec_db.result:
         actionexec_db.result = new_actionexec_db.result
     actionexec_db = ActionExecution.add_or_update(actionexec_db)
     actionexec_api = ActionExecutionAPI.from_model(actionexec_db)
     return actionexec_api
Example #19
0
 def put(self, id, actionexecution):
     try:
         actionexec_db = ActionExecution.get_by_id(id)
     except:
         msg = 'ActionExecution by id: %s not found.' % id
         pecan.abort(http_client, msg)
     new_actionexec_db = ActionExecutionAPI.to_model(actionexecution)
     if actionexec_db.status != new_actionexec_db.status:
         actionexec_db.status = new_actionexec_db.status
     if actionexec_db.result != new_actionexec_db.result:
         actionexec_db.result = new_actionexec_db.result
     actionexec_db = ActionExecution.add_or_update(actionexec_db)
     actionexec_api = ActionExecutionAPI.from_model(actionexec_db)
     return actionexec_api
Example #20
0
    def test_retry_on_timeout_first_retry_is_successful(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which times out
        liveaction = LiveActionDB(action='wolfpack.action-1', parameters={'actionstr': 'foo'})
        live_action_db, execution_db = action_service.request(liveaction)

        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should be two objects - original execution and retried execution
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 2)
        self.assertEqual(len(action_execution_dbs), 2)
        self.assertEqual(action_execution_dbs[0].status, LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(action_execution_dbs[1].status, LIVEACTION_STATUS_REQUESTED)

        # Verify retried execution contains policy related context
        original_liveaction_id = action_execution_dbs[0].liveaction['id']

        context = action_execution_dbs[1].context
        self.assertTrue('policies' in context)
        self.assertEqual(context['policies']['retry']['retry_count'], 1)
        self.assertEqual(context['policies']['retry']['applied_policy'], 'test_policy')
        self.assertEqual(context['policies']['retry']['retried_liveaction_id'],
                         original_liveaction_id)

        # Simulate success of second action so no it shouldn't be retried anymore
        live_action_db = live_action_dbs[1]
        live_action_db.status = LIVEACTION_STATUS_SUCCEEDED
        LiveAction.add_or_update(live_action_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should be no new object since action succeeds so no retry was attempted
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 2)
        self.assertEqual(len(action_execution_dbs), 2)
        self.assertEqual(live_action_dbs[0].status, LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(live_action_dbs[1].status, LIVEACTION_STATUS_SUCCEEDED)
Example #21
0
def update_actionexecution_status(new_status,
                                  actionexec_id=None,
                                  actionexec_db=None):
    """
        Update the status of the specified ActionExecution to the value provided in
        new_status.

        The ActionExecution may be specified using either actionexec_id, or as an
        actionexec_db instance.
    """

    if (actionexec_id is None) and (actionexec_db is None):
        raise ValueError(
            'Must specify an actionexec_id or an actionexec_db when '
            'calling update_actionexecution_status')

    if actionexec_db is None:
        actionexec_db = get_actionexec_by_id(actionexec_id)

    if new_status not in ACTIONEXEC_STATUSES:
        raise ValueError(
            'Attempting to set status for ActionExecution "%s" '
            'to unknown status string. Unknown status is "%s"', actionexec_db,
            new_status)

    LOG.debug('Updating ActionExection: "%s" with status="%s"', actionexec_db,
              new_status)
    actionexec_db.status = new_status
    actionexec_db = ActionExecution.add_or_update(actionexec_db)
    LOG.debug('Updated status for ActionExecution object: %s', actionexec_db)
    return actionexec_db
Example #22
0
def update_actionexecution_status(new_status, actionexec_id=None, actionexec_db=None):
    """
        Update the status of the specified ActionExecution to the value provided in
        new_status.

        The ActionExecution may be specified using either actionexec_id, or as an
        actionexec_db instance.
    """

    if (actionexec_id is None) and (actionexec_db is None):
        raise ValueError('Must specify an actionexec_id or an actionexec_db when '
                         'calling update_actionexecution_status')

    if actionexec_db is None:
        actionexec_db = get_actionexec_by_id(actionexec_id)

    if new_status not in ACTIONEXEC_STATUSES:
        raise ValueError('Attempting to set status for ActionExecution "%s" '
                         'to unknown status string. Unknown status is "%s"',
                         actionexec_db, new_status)

    LOG.debug('Updating ActionExection: "%s" with status="%s"',
              actionexec_db, new_status)
    actionexec_db.status = new_status
    actionexec_db = ActionExecution.add_or_update(actionexec_db)
    LOG.debug('Updated status for ActionExecution object: %s', actionexec_db)
    return actionexec_db
    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')
Example #24
0
    def setup_action_models(cls):
        action_db = ActionDB()
        action_db.name = 'action-1'
        action_db.description = 'awesomeness'
        action_db.enabled = True
        action_db.pack = 'wolfpack'
        action_db.entry_point = ''
        action_db.runner_type = {'name': 'test-runner'}
        action_db.parameters = {
            'actionstr': {'type': 'string', 'position': 1, 'required': True},
            'actionint': {'type': 'number', 'default': 10, 'position': 0},
            'runnerdummy': {'type': 'string', 'default': 'actiondummy'}
        }
        ActionDBUtilsTestCase.action_db = Action.add_or_update(action_db)

        actionexec_db = ActionExecutionDB()
        actionexec_db.status = 'initializing'
        actionexec_db.start_timestamp = datetime.datetime.utcnow()
        actionexec_db.action = ResourceReference(
            name=ActionDBUtilsTestCase.action_db.name,
            pack=ActionDBUtilsTestCase.action_db.pack).ref
        params = {
            'actionstr': 'foo',
            'some_key_that_aint_exist_in_action_or_runner': 'bar',
            'runnerint': 555
        }
        actionexec_db.parameters = params
        ActionDBUtilsTestCase.actionexec_db = ActionExecution.add_or_update(actionexec_db)
Example #25
0
    def record_action_execution(self, body):
        try:
            history_id = bson.ObjectId()
            execution = ActionExecution.get_by_id(str(body.id))
            action_ref = ResourceReference.from_string_reference(
                ref=execution.action)
            action_db, _ = action_utils.get_action_by_dict({
                'name':
                action_ref.name,
                'pack':
                action_ref.pack
            })
            runner = RunnerType.get_by_name(action_db.runner_type['name'])

            attrs = {
                'id': history_id,
                'action': vars(ActionAPI.from_model(action_db)),
                'runner': vars(RunnerTypeAPI.from_model(runner)),
                'execution': vars(ActionExecutionAPI.from_model(execution))
            }

            if 'rule' in execution.context:
                rule = reference.get_model_from_ref(
                    Rule, execution.context.get('rule', {}))
                attrs['rule'] = vars(RuleAPI.from_model(rule))

            if 'trigger_instance' in execution.context:
                trigger_instance_id = execution.context.get(
                    'trigger_instance', {})
                trigger_instance_id = trigger_instance_id.get('id', None)
                trigger_instance = TriggerInstance.get_by_id(
                    trigger_instance_id)
                trigger = reference.get_model_by_resource_ref(
                    db_api=Trigger, ref=trigger_instance.trigger)
                trigger_type = reference.get_model_by_resource_ref(
                    db_api=TriggerType, ref=trigger.type)
                trigger_instance = reference.get_model_from_ref(
                    TriggerInstance,
                    execution.context.get('trigger_instance', {}))
                attrs['trigger_instance'] = vars(
                    TriggerInstanceAPI.from_model(trigger_instance))
                attrs['trigger'] = vars(TriggerAPI.from_model(trigger))
                attrs['trigger_type'] = vars(
                    TriggerTypeAPI.from_model(trigger_type))

            parent = ActionExecutionHistory.get(
                execution__id=execution.context.get('parent', ''))
            if parent:
                attrs['parent'] = str(parent.id)
                if str(history_id) not in parent.children:
                    parent.children.append(str(history_id))
                    ActionExecutionHistory.add_or_update(parent)

            history = ActionExecutionHistoryDB(**attrs)
            history = ActionExecutionHistory.add_or_update(history)
        except:
            LOG.exception('An unexpected error occurred while creating the '
                          'action execution history.')
            raise
Example #26
0
 def test_launch_workflow(self):
     MistralRunner.entry_point = mock.PropertyMock(
         return_value=WORKFLOW_YAML)
     execution = ActionExecutionDB(action='core.workflow-v2',
                                   parameters={'friend': 'Rocky'})
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_RUNNING)
    def test_retry_on_timeout_first_retry_is_successful(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which times out
        liveaction = LiveActionDB(action='wolfpack.action-1',
                                  parameters={'actionstr': 'foo'})
        live_action_db, execution_db = action_service.request(liveaction)

        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should be two objects - original execution and retried execution
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 2)
        self.assertEqual(len(action_execution_dbs), 2)
        self.assertEqual(action_execution_dbs[0].status,
                         LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(action_execution_dbs[1].status,
                         LIVEACTION_STATUS_REQUESTED)

        # Simulate success of second action so no it shouldn't be retried anymore
        live_action_db = live_action_dbs[1]
        live_action_db.status = LIVEACTION_STATUS_SUCCEEDED
        LiveAction.add_or_update(live_action_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should be no new object since action succeeds so no retry was attempted
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 2)
        self.assertEqual(len(action_execution_dbs), 2)
        self.assertEqual(live_action_dbs[0].status,
                         LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(live_action_dbs[1].status,
                         LIVEACTION_STATUS_SUCCEEDED)
Example #28
0
 def test_basic_execution(self):
     action_ref = ResourceReference(name='local', pack='core')
     execution = ActionExecutionDB(action=action_ref.ref, parameters={'cmd': 'uname -a'})
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED)
     history = ActionExecutionHistory.get(execution__id=str(execution.id), raise_exception=True)
     self.assertDictEqual(history.trigger, {})
     self.assertDictEqual(history.trigger_type, {})
     self.assertDictEqual(history.trigger_instance, {})
     self.assertDictEqual(history.rule, {})
     action, _ = action_utils.get_action_by_dict(
         {'name': action_ref.name, 'pack': action_ref.pack})
     self.assertDictEqual(history.action, vars(ActionAPI.from_model(action)))
     runner = RunnerType.get_by_name(action.runner_type['name'])
     self.assertDictEqual(history.runner, vars(RunnerTypeAPI.from_model(runner)))
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertDictEqual(history.execution, vars(ActionExecutionAPI.from_model(execution)))
Example #29
0
 def test_callback(self):
     execution = ActionExecutionDB(
         action='core.local', parameters={'cmd': 'uname -a'},
         callback={'source': 'mistral', 'url': 'http://localhost:8989/v2/tasks/12345'})
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED)
     requests.request.assert_called_with('PUT', execution.callback['url'],
                                         data=json.dumps({'state': 'SUCCESS', 'result': '{}'}),
                                         headers={'content-type': 'application/json'})
Example #30
0
 def test_chained_executions(self):
     action_ref = ResourceReference(name='chain', pack='core')
     execution = ActionExecutionDB(action=action_ref.ref)
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED)
     history = ActionExecutionHistory.get(execution__id=str(execution.id), raise_exception=True)
     action, _ = action_utils.get_action_by_dict(
         {'name': action_ref.name, 'pack': action_ref.pack})
     self.assertDictEqual(history.action, vars(ActionAPI.from_model(action)))
     runner = RunnerType.get_by_name(action.runner_type['name'])
     self.assertDictEqual(history.runner, vars(RunnerTypeAPI.from_model(runner)))
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertDictEqual(history.execution, vars(ActionExecutionAPI.from_model(execution)))
     self.assertGreater(len(history.children), 0)
     for child in history.children:
         record = ActionExecutionHistory.get(id=child, raise_exception=True)
         self.assertEqual(record.parent, str(history.id))
         self.assertEqual(record.action['name'], 'local')
         self.assertEqual(record.runner['name'], 'run-local')
Example #31
0
def schedule(execution):

    # Use the user context from the parent action execution. Subtasks in a workflow
    # action can be invoked by a system user and so we want to use the user context
    # from the original workflow action.
    if getattr(execution, 'context', None) and 'parent' in execution.context:
        parent = ActionExecution.get_by_id(execution.context['parent'])
        execution.context['user'] = getattr(parent, 'context', dict()).get('user')

    # Validate action.
    action_db = action_utils.get_action_by_ref(execution.action)
    if not action_db:
        raise ValueError('Action "%s" cannot be found.' % execution.action)
    if not action_db.enabled:
        raise ValueError('Unable to execute. Action "%s" is disabled.' % execution.action)

    runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type['name'])

    if not hasattr(execution, 'parameters'):
        execution.parameters = dict()

    # Validate action parameters.
    schema = util_schema.get_parameter_schema(action_db)
    validator = util_schema.get_validator()
    jsonschema.validate(execution.parameters, schema, validator)

    # validate that no immutable params are being overriden. Although possible to
    # ignore the override it is safer to inform the user to avoid surprises.
    immutables = _get_immutable_params(action_db.parameters)
    immutables.extend(_get_immutable_params(runnertype_db.runner_parameters))
    overridden_immutables = [p for p in six.iterkeys(execution.parameters) if p in immutables]
    if len(overridden_immutables) > 0:
        raise ValueError('Override of immutable parameter(s) %s is unsupported.'
                         % str(overridden_immutables))

    # Write to database and send to message queue.
    execution.status = ACTIONEXEC_STATUS_SCHEDULED
    execution.start_timestamp = isotime.add_utc_tz(datetime.datetime.utcnow())
    execution = ActionExecution.add_or_update(execution)
    LOG.audit('Action execution scheduled. ActionExecution=%s.', execution)
    return execution
Example #32
0
 def test_basic_execution(self):
     execution = ActionExecutionDB(action='core.local',
                                   parameters={'cmd': 'uname -a'})
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_FAILED)
     history = ActionExecutionHistory.get(execution__id=str(execution.id),
                                          raise_exception=True)
     self.assertDictEqual(history.trigger, {})
     self.assertDictEqual(history.trigger_type, {})
     self.assertDictEqual(history.trigger_instance, {})
     self.assertDictEqual(history.rule, {})
     action = action_utils.get_action_by_ref('core.local')
     self.assertDictEqual(history.action,
                          vars(ActionAPI.from_model(action)))
     runner = RunnerType.get_by_name(action.runner_type['name'])
     self.assertDictEqual(history.runner,
                          vars(RunnerTypeAPI.from_model(runner)))
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertDictEqual(history.execution,
                          vars(ActionExecutionAPI.from_model(execution)))
Example #33
0
    def test_triggered_execution(self):
        docs = {
            'trigger_type': copy.deepcopy(fixture.ARTIFACTS['trigger_type']),
            'trigger': copy.deepcopy(fixture.ARTIFACTS['trigger']),
            'rule': copy.deepcopy(fixture.ARTIFACTS['rule']),
            'trigger_instance': copy.deepcopy(fixture.ARTIFACTS['trigger_instance'])}

        # Trigger an action execution.
        trigger_type = TriggerType.add_or_update(
            TriggerTypeAPI.to_model(TriggerTypeAPI(**docs['trigger_type'])))
        trigger = Trigger.add_or_update(TriggerAPI.to_model(TriggerAPI(**docs['trigger'])))
        rule = RuleAPI.to_model(RuleAPI(**docs['rule']))
        rule.trigger = reference.get_str_resource_ref_from_model(trigger)
        rule = Rule.add_or_update(rule)
        trigger_instance = TriggerInstance.add_or_update(
            TriggerInstanceAPI.to_model(TriggerInstanceAPI(**docs['trigger_instance'])))
        enforcer = RuleEnforcer(trigger_instance, rule)
        enforcer.enforce()

        # Wait for the action execution to complete and then confirm outcome.
        execution = ActionExecution.get(context__trigger_instance__id=str(trigger_instance.id))
        self.assertIsNotNone(execution)
        execution = ActionExecution.get_by_id(str(execution.id))
        self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED)
        history = ActionExecutionHistory.get(execution__id=str(execution.id), raise_exception=True)
        self.assertDictEqual(history.trigger, vars(TriggerAPI.from_model(trigger)))
        self.assertDictEqual(history.trigger_type, vars(TriggerTypeAPI.from_model(trigger_type)))
        self.assertDictEqual(history.trigger_instance,
                             vars(TriggerInstanceAPI.from_model(trigger_instance)))
        self.assertDictEqual(history.rule, vars(RuleAPI.from_model(rule)))
        action_ref = ResourceReference.from_string_reference(ref=execution.action)
        action, _ = action_utils.get_action_by_dict(
            {'name': action_ref.name, 'pack': action_ref.pack})
        self.assertDictEqual(history.action, vars(ActionAPI.from_model(action)))
        runner = RunnerType.get_by_name(action.runner_type['name'])
        self.assertDictEqual(history.runner, vars(RunnerTypeAPI.from_model(runner)))
        execution = ActionExecution.get_by_id(str(execution.id))
        self.assertDictEqual(history.execution, vars(ActionExecutionAPI.from_model(execution)))
Example #34
0
    def test_retry_on_timeout_no_retry_since_no_timeout_reached(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which succeeds
        liveaction = LiveActionDB(action='wolfpack.action-1', parameters={'actionstr': 'foo'})
        live_action_db, execution_db = action_service.request(liveaction)

        live_action_db.status = LIVEACTION_STATUS_SUCCEEDED
        execution_db.status = LIVEACTION_STATUS_SUCCEEDED
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should only be 1 object since the action didn't timeout and therefore it wasn't
        # retried
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 1)
        self.assertEqual(len(action_execution_dbs), 1)
        self.assertEqual(action_execution_dbs[0].status, LIVEACTION_STATUS_SUCCEEDED)
Example #35
0
    def record_action_execution(self, body):
        try:
            history_id = bson.ObjectId()
            execution = ActionExecution.get_by_id(str(body.id))
            action_ref = ResourceReference.from_string_reference(ref=execution.action)
            action_db, _ = action_utils.get_action_by_dict(
                {'name': action_ref.name,
                 'pack': action_ref.pack})
            runner = RunnerType.get_by_name(action_db.runner_type['name'])

            attrs = {
                'id': history_id,
                'action': vars(ActionAPI.from_model(action_db)),
                'runner': vars(RunnerTypeAPI.from_model(runner)),
                'execution': vars(ActionExecutionAPI.from_model(execution))
            }

            if 'rule' in execution.context:
                rule = reference.get_model_from_ref(Rule, execution.context.get('rule', {}))
                attrs['rule'] = vars(RuleAPI.from_model(rule))

            if 'trigger_instance' in execution.context:
                trigger_instance_id = execution.context.get('trigger_instance', {})
                trigger_instance_id = trigger_instance_id.get('id', None)
                trigger_instance = TriggerInstance.get_by_id(trigger_instance_id)
                trigger = reference.get_model_by_resource_ref(db_api=Trigger,
                                                              ref=trigger_instance.trigger)
                trigger_type = reference.get_model_by_resource_ref(db_api=TriggerType,
                                                                   ref=trigger.type)
                trigger_instance = reference.get_model_from_ref(
                    TriggerInstance, execution.context.get('trigger_instance', {}))
                attrs['trigger_instance'] = vars(TriggerInstanceAPI.from_model(trigger_instance))
                attrs['trigger'] = vars(TriggerAPI.from_model(trigger))
                attrs['trigger_type'] = vars(TriggerTypeAPI.from_model(trigger_type))

            parent = ActionExecutionHistory.get(execution__id=execution.context.get('parent', ''))
            if parent:
                attrs['parent'] = str(parent.id)
                if str(history_id) not in parent.children:
                    parent.children.append(str(history_id))
                    ActionExecutionHistory.add_or_update(parent)

            history = ActionExecutionHistoryDB(**attrs)
            history = ActionExecutionHistory.add_or_update(history)
        except:
            LOG.exception('An unexpected error occurred while creating the '
                          'action execution history.')
            raise
Example #36
0
def get_actionexec_by_id(actionexec_id):
    """
        Get ActionExecution by id.

        On error, raise ST2DBObjectNotFoundError.
    """
    actionexec = None

    try:
        actionexec = ActionExecution.get_by_id(actionexec_id)
    except (ValidationError, ValueError) as e:
        LOG.error('Database lookup for actionexecution with id="%s" resulted in '
                  'exception: %s', actionexec_id, e)
        raise StackStormDBObjectNotFoundError('Unable to find actionexecution with '
                                              'id="%s"' % actionexec_id)

    return actionexec
Example #37
0
 def test_schedule(self):
     context = {'user': USERNAME}
     parameters = {'hosts': 'localhost', 'cmd': 'uname -a'}
     request = ActionExecutionDB(action=ACTION_REF, context=context, parameters=parameters)
     request = action_service.schedule(request)
     execution = ActionExecution.get_by_id(str(request.id))
     self.assertIsNotNone(execution)
     self.assertEqual(execution.id, request.id)
     action = '.'.join([self.actiondb.pack, self.actiondb.name])
     actual_action = execution.action
     self.assertEqual(actual_action, action)
     self.assertEqual(execution.context['user'], request.context['user'])
     self.assertDictEqual(execution.parameters, request.parameters)
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_SCHEDULED)
     # mongoengine DateTimeField stores datetime only up to milliseconds
     self.assertEqual(isotime.format(execution.start_timestamp, usec=False),
                      isotime.format(request.start_timestamp, usec=False))
Example #38
0
    def test_update_actionexecution_status_invalid(self):
        actionexec_db = ActionExecutionDB()
        actionexec_db.status = 'initializing'
        actionexec_db.start_timestamp = datetime.datetime.utcnow()
        actionexec_db.action = ResourceReference(
            name=ActionDBUtilsTestCase.action_db.name,
            pack=ActionDBUtilsTestCase.action_db.pack).ref
        params = {
            'actionstr': 'foo',
            'some_key_that_aint_exist_in_action_or_runner': 'bar',
            'runnerint': 555
        }
        actionexec_db.parameters = params
        actionexec_db = ActionExecution.add_or_update(actionexec_db)

        # Update by id.
        self.assertRaises(ValueError, action_db_utils.update_actionexecution_status,
                          'mea culpa', actionexec_id=actionexec_db.id)
Example #39
0
def get_actionexec_by_id(actionexec_id):
    """
        Get ActionExecution by id.

        On error, raise ST2DBObjectNotFoundError.
    """
    actionexec = None

    try:
        actionexec = ActionExecution.get_by_id(actionexec_id)
    except (ValidationError, ValueError) as e:
        LOG.error(
            'Database lookup for actionexecution with id="%s" resulted in '
            'exception: %s', actionexec_id, e)
        raise StackStormDBObjectNotFoundError(
            'Unable to find actionexecution with '
            'id="%s"' % actionexec_id)

    return actionexec
Example #40
0
 def test_schedule(self):
     context = {'user': USERNAME}
     parameters = {'hosts': 'localhost', 'cmd': 'uname -a'}
     request = ActionExecutionDB(action=ACTION_REF,
                                 context=context,
                                 parameters=parameters)
     request = action_service.schedule(request)
     execution = ActionExecution.get_by_id(str(request.id))
     self.assertIsNotNone(execution)
     self.assertEqual(execution.id, request.id)
     action = '.'.join([self.actiondb.pack, self.actiondb.name])
     actual_action = execution.action
     self.assertEqual(actual_action, action)
     self.assertEqual(execution.context['user'], request.context['user'])
     self.assertDictEqual(execution.parameters, request.parameters)
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_SCHEDULED)
     # mongoengine DateTimeField stores datetime only up to milliseconds
     self.assertEqual(isotime.format(execution.start_timestamp, usec=False),
                      isotime.format(request.start_timestamp, usec=False))
Example #41
0
 def test_callback(self):
     execution = ActionExecutionDB(
         action='core.local',
         parameters={'cmd': 'uname -a'},
         callback={
             'source': 'mistral',
             'url': 'http://localhost:8989/v2/tasks/12345'
         })
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED)
     requests.request.assert_called_with(
         'PUT',
         execution.callback['url'],
         data=json.dumps({
             'state': 'SUCCESS',
             'result': '{}'
         }),
         headers={'content-type': 'application/json'})
Example #42
0
 def update_action_execution_history(self, body):
     try:
         count = self.timeout / self.wait
         # Allow up to 1 minute for the post event to create the history record.
         for i in range(count):
             history = ActionExecutionHistory.get(execution__id=str(body.id))
             if history:
                 execution = ActionExecution.get_by_id(str(body.id))
                 history.execution = vars(ActionExecutionAPI.from_model(execution))
                 history = ActionExecutionHistory.add_or_update(history)
                 return
             if i >= count:
                 # If wait failed, create the history record regardless.
                 self.record_action_execution(body)
                 return
             eventlet.sleep(self.wait)
     except:
         LOG.exception('An unexpected error occurred while updating the '
                       'action execution history.')
         raise
Example #43
0
 def update_action_execution_history(self, body):
     try:
         count = self.timeout / self.wait
         # Allow up to 1 minute for the post event to create the history record.
         for i in range(count):
             history = ActionExecutionHistory.get(execution__id=str(body.id))
             if history:
                 execution = ActionExecution.get_by_id(str(body.id))
                 history.execution = vars(ActionExecutionAPI.from_model(execution))
                 history = ActionExecutionHistory.add_or_update(history)
                 return
             if i >= count:
                 # If wait failed, create the history record regardless.
                 self.record_action_execution(body)
                 return
             eventlet.sleep(self.wait)
     except:
         LOG.exception('An unexpected error occurred while updating the '
                       'action execution history.')
         raise
Example #44
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)
Example #45
0
    def test_update_actionexecution_status(self):
        actionexec_db = ActionExecutionDB()
        actionexec_db.status = 'initializing'
        actionexec_db.start_timestamp = datetime.datetime.utcnow()
        actionexec_db.action = ResourceReference(
            name=ActionDBUtilsTestCase.action_db.name,
            pack=ActionDBUtilsTestCase.action_db.pack).ref
        params = {
            'actionstr': 'foo',
            'some_key_that_aint_exist_in_action_or_runner': 'bar',
            'runnerint': 555
        }
        actionexec_db.parameters = params
        actionexec_db = ActionExecution.add_or_update(actionexec_db)
        origactionexec_db = copy.copy(actionexec_db)

        # Update by id.
        newactionexec_db = action_db_utils.update_actionexecution_status(
            'running', actionexec_id=actionexec_db.id)
        # Verify id didn't change.
        self.assertEqual(origactionexec_db.id, newactionexec_db.id)
        self.assertEqual(newactionexec_db.status, 'running')
Example #46
0
    def test_update_actionexecution_status_and_end_timestamp(self):
        actionexec_db = ActionExecutionDB()
        actionexec_db.status = 'initializing'
        actionexec_db.start_timestamp = datetime.datetime.utcnow()
        actionexec_db.action = ResourceReference(
            name=ActionDBUtilsTestCase.action_db.name,
            pack=ActionDBUtilsTestCase.action_db.pack).ref
        actionexec_db.parameters = {}
        actionexec_db = ActionExecution.add_or_update(actionexec_db)
        origactionexec_db = copy.copy(actionexec_db)

        # Update by id
        now = datetime.datetime.now()
        newactionexec_db = action_db_utils.update_actionexecution_status(
            status='running',
            end_timestamp=now,
            actionexec_id=actionexec_db.id)

        # Verify id didn't change and end_timestamp has been set
        self.assertEqual(origactionexec_db.id, newactionexec_db.id)
        self.assertEqual(newactionexec_db.status, 'running')
        self.assertEqual(newactionexec_db.end_timestamp, now)
Example #47
0
 def test_launch_workflow_when_definition_changed(self):
     MistralRunner.entry_point = mock.PropertyMock(return_value=WORKFLOW_YAML)
     execution = ActionExecutionDB(action='core.workflow-v2', parameters={'friend': 'Rocky'})
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_RUNNING)
Example #48
0
    def test_retry_on_timeout_policy_is_retried_twice(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which times out
        liveaction = LiveActionDB(action='wolfpack.action-1',
                                  parameters={'actionstr': 'foo'})
        live_action_db, execution_db = action_service.request(liveaction)

        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should be two objects - original execution and retried execution
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 2)
        self.assertEqual(len(action_execution_dbs), 2)
        self.assertEqual(action_execution_dbs[0].status,
                         LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(action_execution_dbs[1].status,
                         LIVEACTION_STATUS_REQUESTED)

        # Verify retried execution contains policy related context
        original_liveaction_id = action_execution_dbs[0].liveaction['id']

        context = action_execution_dbs[1].context
        self.assertTrue('policies' in context)
        self.assertEqual(context['policies']['retry']['retry_count'], 1)
        self.assertEqual(context['policies']['retry']['applied_policy'],
                         'test_policy')
        self.assertEqual(context['policies']['retry']['retried_liveaction_id'],
                         original_liveaction_id)

        # Simulate timeout of second action which should cause another retry
        live_action_db = live_action_dbs[1]
        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)

        execution_db = action_execution_dbs[1]
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should be three objects - original execution and 2 retried executions
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 3)
        self.assertEqual(len(action_execution_dbs), 3)
        self.assertEqual(action_execution_dbs[0].status,
                         LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(action_execution_dbs[1].status,
                         LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(action_execution_dbs[2].status,
                         LIVEACTION_STATUS_REQUESTED)

        # Verify retried execution contains policy related context
        original_liveaction_id = action_execution_dbs[1].liveaction['id']

        context = action_execution_dbs[2].context
        self.assertTrue('policies' in context)
        self.assertEqual(context['policies']['retry']['retry_count'], 2)
        self.assertEqual(context['policies']['retry']['applied_policy'],
                         'test_policy')
        self.assertEqual(context['policies']['retry']['retried_liveaction_id'],
                         original_liveaction_id)
Example #49
0
    def test_retry_on_timeout_policy_is_retried_twice(self):
        # Verify initial state
        self.assertSequenceEqual(LiveAction.get_all(), [])
        self.assertSequenceEqual(ActionExecution.get_all(), [])

        # Start a mock action which times out
        liveaction = LiveActionDB(action='wolfpack.action-1', parameters={'actionstr': 'foo'})
        live_action_db, execution_db = action_service.request(liveaction)

        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should be two objects - original execution and retried execution
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 2)
        self.assertEqual(len(action_execution_dbs), 2)
        self.assertEqual(action_execution_dbs[0].status, LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(action_execution_dbs[1].status, LIVEACTION_STATUS_REQUESTED)

        # Verify retried execution contains policy related context
        original_liveaction_id = action_execution_dbs[0].liveaction['id']

        context = action_execution_dbs[1].context
        self.assertTrue('policies' in context)
        self.assertEqual(context['policies']['retry']['retry_count'], 1)
        self.assertEqual(context['policies']['retry']['applied_policy'], 'test_policy')
        self.assertEqual(context['policies']['retry']['retried_liveaction_id'],
                         original_liveaction_id)

        # Simulate timeout of second action which should cause another retry
        live_action_db = live_action_dbs[1]
        live_action_db.status = LIVEACTION_STATUS_TIMED_OUT
        LiveAction.add_or_update(live_action_db)

        execution_db = action_execution_dbs[1]
        execution_db.status = LIVEACTION_STATUS_TIMED_OUT
        ActionExecution.add_or_update(execution_db)

        # Simulate policy "apply_after" run
        self.policy.apply_after(target=live_action_db)

        # There should be three objects - original execution and 2 retried executions
        live_action_dbs = LiveAction.get_all()
        action_execution_dbs = ActionExecution.get_all()
        self.assertEqual(len(live_action_dbs), 3)
        self.assertEqual(len(action_execution_dbs), 3)
        self.assertEqual(action_execution_dbs[0].status, LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(action_execution_dbs[1].status, LIVEACTION_STATUS_TIMED_OUT)
        self.assertEqual(action_execution_dbs[2].status, LIVEACTION_STATUS_REQUESTED)

        # Verify retried execution contains policy related context
        original_liveaction_id = action_execution_dbs[1].liveaction['id']

        context = action_execution_dbs[2].context
        self.assertTrue('policies' in context)
        self.assertEqual(context['policies']['retry']['retry_count'], 2)
        self.assertEqual(context['policies']['retry']['applied_policy'], 'test_policy')
        self.assertEqual(context['policies']['retry']['retried_liveaction_id'],
                         original_liveaction_id)
Example #50
0
 def test_launch_workflow_when_workbook_not_exists(self):
     execution = ActionExecutionDB(action='core.workflow-v2',
                                   parameters={'friend': 'Rocky'})
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_RUNNING)
Example #51
0
 def test_launch_workflow_when_workbook_not_exists(self):
     execution = ActionExecutionDB(action='core.workflow-v2', parameters={'friend': 'Rocky'})
     execution = action_service.schedule(execution)
     execution = ActionExecution.get_by_id(str(execution.id))
     self.assertEqual(execution.status, ACTIONEXEC_STATUS_RUNNING)