Esempio n. 1
0
    def test_update_same_liveaction_status(self):
        liveaction_db = LiveActionDB()
        liveaction_db.status = 'requested'
        liveaction_db.start_timestamp = get_datetime_utc_now()
        liveaction_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
        }
        liveaction_db.parameters = params
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        origliveaction_db = copy.copy(liveaction_db)

        # Update by id.
        newliveaction_db = action_db_utils.update_liveaction_status(
            status='requested', liveaction_id=liveaction_db.id)

        # Verify id didn't change.
        self.assertEqual(origliveaction_db.id, newliveaction_db.id)
        self.assertEqual(newliveaction_db.status, 'requested')

        # Verify that state is not published.
        self.assertFalse(LiveActionPublisher.publish_state.called)
Esempio n. 2
0
    def setup_action_models(cls):
        pack = 'wolfpack'
        name = 'action-1'
        parameters = {
            'actionint': {'type': 'number', 'default': 10, 'position': 0},
            'actionfloat': {'type': 'float', 'required': False, 'position': 1},
            'actionstr': {'type': 'string', 'required': True, 'position': 2},
            'actionbool': {'type': 'boolean', 'required': False, 'position': 3},
            'actionlist': {'type': 'list', 'required': False, 'position': 4},
            'actionobject': {'type': 'object', 'required': False, 'position': 5},
            'actionnull': {'type': 'null', 'required': False, 'position': 6},

            'runnerdummy': {'type': 'string', 'default': 'actiondummy'}
        }
        action_db = ActionDB(pack=pack, name=name, description='awesomeness',
                             enabled=True,
                             ref=ResourceReference(name=name, pack=pack).ref,
                             entry_point='', runner_type={'name': 'test-runner'},
                             parameters=parameters)
        ActionDBUtilsTestCase.action_db = Action.add_or_update(action_db)

        liveaction_db = LiveActionDB()
        liveaction_db.status = 'initializing'
        liveaction_db.start_timestamp = get_datetime_utc_now()
        liveaction_db.action = ActionDBUtilsTestCase.action_db.ref
        params = {
            'actionstr': 'foo',
            'some_key_that_aint_exist_in_action_or_runner': 'bar',
            'runnerint': 555
        }
        liveaction_db.parameters = params
        ActionDBUtilsTestCase.liveaction_db = LiveAction.add_or_update(liveaction_db)
Esempio n. 3
0
    def post(self, execution_parameters, execution_id):
        """
        Re-run the provided action execution optionally specifying override parameters.

        Handles requests:

            POST /executions/<id>/re_run
        """
        parameters = execution_parameters.parameters

        # Note: We only really need parameters here
        existing_execution = self._get_one(id=execution_id, exclude_fields=self.exclude_fields)

        # Merge in any parameters provided by the user
        new_parameters = copy.deepcopy(existing_execution.parameters)
        new_parameters.update(parameters)

        # Create object for the new execution
        action_ref = existing_execution.action['ref']

        new_execution = LiveActionDB()
        new_execution.action = action_ref
        new_execution.parameters = new_parameters

        result = self._handle_schedule_execution(execution=new_execution)
        return result
Esempio n. 4
0
    def test_process_post_generic_notify_trigger_on_custom_emit_when_states(self,
            mock_LiveAction, mock_dispatch):
        # Verify that generic action trigger is posted on all completed states when action sensor
        # is enabled
        for status in LIVEACTION_STATUSES:
            notifier = Notifier(connection=None, queues=[])

            liveaction_db = LiveActionDB(id=bson.ObjectId(), action='core.local')
            liveaction_db.status = status
            execution = MOCK_EXECUTION
            execution.liveaction = vars(LiveActionAPI.from_model(liveaction_db))
            execution.status = liveaction_db.status

            mock_LiveAction.get_by_id.return_value = liveaction_db

            notifier = Notifier(connection=None, queues=[])
            notifier.process(execution)

            if status in ['scheduled', 'pending', 'abandoned']:
                exp = {'status': status,
                       'start_timestamp': str(liveaction_db.start_timestamp),
                       'result': {}, 'parameters': {},
                       'action_ref': u'core.local',
                       'runner_ref': 'local-shell-cmd',
                       'execution_id': str(MOCK_EXECUTION.id),
                       'action_name': u'core.local'}
                mock_dispatch.assert_called_with('core.st2.generic.actiontrigger',
                                                 payload=exp, trace_context={})

        self.assertEqual(mock_dispatch.call_count, 3)
Esempio n. 5
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.ref = ResourceReference(name=action_db.name, pack=action_db.pack).ref
        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)

        liveaction_db = LiveActionDB()
        liveaction_db.status = 'initializing'
        liveaction_db.start_timestamp = get_datetime_utc_now()
        liveaction_db.action = ActionDBUtilsTestCase.action_db.ref
        params = {
            'actionstr': 'foo',
            'some_key_that_aint_exist_in_action_or_runner': 'bar',
            'runnerint': 555
        }
        liveaction_db.parameters = params
        ActionDBUtilsTestCase.liveaction_db = LiveAction.add_or_update(liveaction_db)
Esempio n. 6
0
    def _run_action(self, action_node, parent_execution_id, params, wait_for_completion=True):
        liveaction = LiveActionDB(action=action_node.ref)
        liveaction.parameters = action_param_utils.cast_params(action_ref=action_node.ref,
                                                               params=params)

        # Setup notify for task in chain.
        notify = self._get_notify(action_node)
        if notify:
            liveaction.notify = notify
            LOG.debug('%s: Task notify set to: %s', action_node.name, liveaction.notify)

        liveaction.context = {
            'parent': str(parent_execution_id),
            'chain': vars(action_node)
        }

        liveaction, _ = action_service.request(liveaction)

        while (wait_for_completion and
               liveaction.status != LIVEACTION_STATUS_SUCCEEDED and
               liveaction.status != LIVEACTION_STATUS_FAILED):
            eventlet.sleep(1)
            liveaction = action_db_util.get_liveaction_by_id(liveaction.id)

        return liveaction
Esempio n. 7
0
 def _create_inquiry(self, ttl, timestamp):
     action_db = self.models['actions']['ask.yaml']
     liveaction_db = LiveActionDB()
     liveaction_db.status = action_constants.LIVEACTION_STATUS_PENDING
     liveaction_db.start_timestamp = timestamp
     liveaction_db.action = ResourceReference(name=action_db.name, pack=action_db.pack).ref
     liveaction_db.result = {'ttl': ttl}
     liveaction_db = LiveAction.add_or_update(liveaction_db)
     executions.create_execution_object(liveaction_db)
Esempio n. 8
0
    def _get_action_exec_db_model(self, params):
        liveaction_db = LiveActionDB()
        liveaction_db.status = 'initializing'
        liveaction_db.start_timestamp = datetime.datetime.utcnow()
        liveaction_db.action = ResourceReference(name=ParamsUtilsTest.action_db.name,
                                                 pack=ParamsUtilsTest.action_db.pack).ref
        liveaction_db.parameters = params

        return liveaction_db
Esempio n. 9
0
 def _get_execution_db_model(self, status=action_constants.LIVEACTION_STATUS_REQUESTED):
     live_action_db = LiveActionDB()
     live_action_db.status = status
     live_action_db.start_timestamp = date_utils.get_datetime_utc_now()
     live_action_db.action = ResourceReference(
         name='test_action',
         pack='test_pack').ref
     live_action_db.parameters = None
     return action.LiveAction.add_or_update(live_action_db, publish=False)
Esempio n. 10
0
    def _get_liveaction_model(self, params):
        status = 'initializing'
        start_timestamp = date_utils.get_datetime_utc_now()
        action_ref = ResourceReference(name=ParamsUtilsTest.action_db.name,
                                       pack=ParamsUtilsTest.action_db.pack).ref
        liveaction_db = LiveActionDB(status=status, start_timestamp=start_timestamp,
                                     action=action_ref, parameters=params)
        liveaction_db.context = {'source_channel': 'awesome', 'api_user': '******'}

        return liveaction_db
Esempio n. 11
0
    def test_notify_triggers_jinja_patterns(self, dispatch):
        liveaction_db = LiveActionDB(action='core.local')
        liveaction_db.id = bson.ObjectId()
        liveaction_db.description = ''
        liveaction_db.status = 'succeeded'
        liveaction_db.parameters = {'cmd': 'mamma mia', 'runner_foo': 'foo'}
        on_success = NotificationSubSchema(message='Command {{action_parameters.cmd}} succeeded.',
                                           data={'stdout': '{{action_results.stdout}}'})
        liveaction_db.notify = NotificationSchema(on_success=on_success)
        liveaction_db.start_timestamp = date_utils.get_datetime_utc_now()
        liveaction_db.end_timestamp = \
            (liveaction_db.start_timestamp + datetime.timedelta(seconds=50))

        LiveAction.add_or_update(liveaction_db)

        execution = MOCK_EXECUTION
        execution.liveaction = vars(LiveActionAPI.from_model(liveaction_db))
        execution.status = liveaction_db.status

        notifier = Notifier(connection=None, queues=[])
        notifier.process(execution)
        exp = {'status': 'succeeded',
               'start_timestamp': isotime.format(liveaction_db.start_timestamp),
               'route': 'notify.default', 'runner_ref': 'local-shell-cmd',
               'channel': 'notify.default', 'message': u'Command mamma mia succeeded.',
               'data': {'result': '{}', 'stdout': 'stuff happens'},
               'action_ref': u'core.local',
               'execution_id': str(MOCK_EXECUTION.id),
               'end_timestamp': isotime.format(liveaction_db.end_timestamp)}
        dispatch.assert_called_once_with('core.st2.generic.notifytrigger', payload=exp,
                                         trace_context={})
        notifier.process(execution)
Esempio n. 12
0
    def test_notify_triggers_end_timestamp_none(self):
        liveaction_db = LiveActionDB(action='core.local')
        liveaction_db.id = bson.ObjectId()
        liveaction_db.description = ''
        liveaction_db.status = 'succeeded'
        liveaction_db.parameters = {}
        on_success = NotificationSubSchema(message='Action succeeded.')
        on_failure = NotificationSubSchema(message='Action failed.')
        liveaction_db.notify = NotificationSchema(on_success=on_success,
                                                  on_failure=on_failure)
        liveaction_db.start_timestamp = date_utils.get_datetime_utc_now()

        # This tests for end_timestamp being set to None, which can happen when a policy cancels
        # a request.
        # The assertions within "MockDispatcher.dispatch" will validate that the underlying code
        # handles this properly, so all we need to do is keep the call to "notifier.process" below
        liveaction_db.end_timestamp = None
        LiveAction.add_or_update(liveaction_db)

        execution = MOCK_EXECUTION
        execution.liveaction = vars(LiveActionAPI.from_model(liveaction_db))
        execution.status = liveaction_db.status

        dispatcher = NotifierTestCase.MockDispatcher(self)
        notifier = Notifier(connection=None, queues=[], trigger_dispatcher=dispatcher)
        notifier.process(execution)
Esempio n. 13
0
    def _build_liveaction_object(self, action_node, resolved_params, parent_context):
        liveaction = LiveActionDB(action=action_node.ref)

        # Setup notify for task in chain.
        notify = self._get_notify(action_node)
        if notify:
            liveaction.notify = notify
            LOG.debug('%s: Task notify set to: %s', action_node.name, liveaction.notify)

        liveaction.context = {
            'parent': parent_context,
            'chain': vars(action_node)
        }
        liveaction.parameters = action_param_utils.cast_params(action_ref=action_node.ref,
                                                               params=resolved_params)
        return liveaction
Esempio n. 14
0
    def _invoke_action(self, action_db, runnertype_db, params, context=None,
                       additional_contexts=None):
        """
        Schedule an action execution.

        :type action_exec_spec: :class:`ActionExecutionSpecDB`

        :param params: Partially rendered parameters to execute the action with.
        :type params: ``dict``

        :rtype: :class:`LiveActionDB` on successful scheduling, None otherwise.
        """
        action_ref = action_db.ref
        runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type['name'])

        liveaction_db = LiveActionDB(action=action_ref, context=context, parameters=params)

        try:
            liveaction_db.parameters = self.get_resolved_parameters(
                runnertype_db=runnertype_db,
                action_db=action_db,
                params=liveaction_db.parameters,
                context=liveaction_db.context,
                additional_contexts=additional_contexts)
        except param_exc.ParamException as e:
            # We still need to create a request, so liveaction_db is assigned an ID
            liveaction_db, execution_db = action_service.create_request(liveaction_db)

            # By this point the execution is already in the DB therefore need to mark it failed.
            _, e, tb = sys.exc_info()
            action_service.update_status(
                liveaction=liveaction_db,
                new_status=action_constants.LIVEACTION_STATUS_FAILED,
                result={'error': six.text_type(e),
                        'traceback': ''.join(traceback.format_tb(tb, 20))})

            # Might be a good idea to return the actual ActionExecution rather than bubble up
            # the exception.
            raise validation_exc.ValueValidationException(six.text_type(e))

        liveaction_db, execution_db = action_service.request(liveaction_db)

        return execution_db
Esempio n. 15
0
    def test_update_liveaction_result_with_dotted_key(self):
        liveaction_db = LiveActionDB()
        liveaction_db.status = 'initializing'
        liveaction_db.start_timestamp = get_datetime_utc_now()
        liveaction_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
        }
        liveaction_db.parameters = params
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        origliveaction_db = copy.copy(liveaction_db)

        # Update by id.
        newliveaction_db = action_db_utils.update_liveaction_status(
            status='running', liveaction_id=liveaction_db.id)

        # Verify id didn't change.
        self.assertEqual(origliveaction_db.id, newliveaction_db.id)
        self.assertEqual(newliveaction_db.status, 'running')

        # Verify that state is published.
        self.assertTrue(LiveActionPublisher.publish_state.called)
        LiveActionPublisher.publish_state.assert_called_once_with(newliveaction_db, 'running')

        now = get_datetime_utc_now()
        status = 'succeeded'
        result = {'a': 1, 'b': True, 'a.b.c': 'abc'}
        context = {'third_party_id': uuid.uuid4().hex}
        newliveaction_db = action_db_utils.update_liveaction_status(
            status=status, result=result, context=context, end_timestamp=now,
            liveaction_id=liveaction_db.id)

        self.assertEqual(origliveaction_db.id, newliveaction_db.id)
        self.assertEqual(newliveaction_db.status, status)
        self.assertIn('a.b.c', list(result.keys()))
        self.assertDictEqual(newliveaction_db.result, result)
        self.assertDictEqual(newliveaction_db.context, context)
        self.assertEqual(newliveaction_db.end_timestamp, now)
Esempio n. 16
0
    def get_liveaction_instance(self, status=None, result=None):
        callback = {
            'source': MISTRAL_RUNNER_NAME,
            'url': 'http://127.0.0.1:8989/v2/action_executions/12345'
        }

        liveaction = LiveActionDB(
            action='core.local',
            parameters={'cmd': 'uname -a'},
            callback=callback,
            context=dict()
        )

        if status:
            liveaction.status = status

        if result:
            liveaction.result = result

        return liveaction
Esempio n. 17
0
    def test_update_LiveAction_status_invalid(self):
        liveaction_db = LiveActionDB()
        liveaction_db.status = 'initializing'
        liveaction_db.start_timestamp = get_datetime_utc_now()
        liveaction_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
        }
        liveaction_db.parameters = params
        liveaction_db = LiveAction.add_or_update(liveaction_db)

        # Update by id.
        self.assertRaises(ValueError, action_db_utils.update_liveaction_status,
                          status='mea culpa', liveaction_id=liveaction_db.id)

        # Verify that state is not published.
        self.assertFalse(LiveActionPublisher.publish_state.called)
Esempio n. 18
0
    def _get_liveaction_model(self, params, with_config_context=False):
        status = 'initializing'
        start_timestamp = date_utils.get_datetime_utc_now()
        action_ref = ResourceReference(name=ParamsUtilsTest.action_db.name,
                                       pack=ParamsUtilsTest.action_db.pack).ref
        liveaction_db = LiveActionDB(status=status, start_timestamp=start_timestamp,
                                     action=action_ref, parameters=params)
        liveaction_db.context = {
            'api_user': '******',
            'source_channel': 'reddit',
        }

        if with_config_context:
            liveaction_db.context.update(
                {
                    'pack': 'generic',
                    'user': '******'
                }
            )

        return liveaction_db
Esempio n. 19
0
    def test_liveaction_create_with_notify_on_success_only(self):
        created = LiveActionDB()
        created.action = 'core.local'
        created.description = ''
        created.status = 'running'
        created.parameters = {}
        notify_db = NotificationSchema()
        notify_sub_schema = NotificationSubSchema()
        notify_sub_schema.message = 'Action succeeded.'
        notify_sub_schema.data = {
            'foo': 'bar',
            'bar': 1,
            'baz': {'k1': 'v1'}
        }
        notify_db.on_success = notify_sub_schema
        created.notify = notify_db
        saved = LiveActionModelTest._save_liveaction(created)
        retrieved = LiveAction.get_by_id(saved.id)
        self.assertEqual(saved.action, retrieved.action,
                         'Same triggertype was not returned.')

        # Assert notify settings saved are right.
        self.assertEqual(notify_sub_schema.message,
                         retrieved.notify.on_success.message)
        self.assertDictEqual(notify_sub_schema.data, retrieved.notify.on_success.data)
        self.assertListEqual(notify_sub_schema.routes, retrieved.notify.on_success.routes)
        self.assertEqual(retrieved.notify.on_failure, None)
        self.assertEqual(retrieved.notify.on_complete, None)
Esempio n. 20
0
    def test_post_generic_trigger_with_emit_condition(self, dispatch):
        for status in LIVEACTION_STATUSES:
            liveaction_db = LiveActionDB(action='core.local')
            liveaction_db.status = status
            execution = MOCK_EXECUTION
            execution.liveaction = vars(LiveActionAPI.from_model(liveaction_db))
            execution.status = liveaction_db.status

            notifier = Notifier(connection=None, queues=[])
            notifier._post_generic_trigger(liveaction_db, execution)

            if status in ['scheduled', 'pending', 'abandoned']:
                exp = {'status': status,
                       'start_timestamp': str(liveaction_db.start_timestamp),
                       'result': {}, 'parameters': {},
                       'action_ref': u'core.local',
                       'runner_ref': 'local-shell-cmd',
                       'execution_id': str(MOCK_EXECUTION.id),
                       'action_name': u'core.local'}
                dispatch.assert_called_with('core.st2.generic.actiontrigger',
                                            payload=exp, trace_context={})

        self.assertEqual(dispatch.call_count, 3)
Esempio n. 21
0
    def test_liveaction_crud_no_notify(self):
        created = LiveActionDB()
        created.action = 'core.local'
        created.description = ''
        created.status = 'running'
        created.parameters = {}
        saved = LiveActionModelTest._save_liveaction(created)
        retrieved = LiveAction.get_by_id(saved.id)
        self.assertEqual(saved.action, retrieved.action,
                         'Same triggertype was not returned.')
        self.assertEqual(retrieved.notify, None)

        # Test update
        self.assertTrue(retrieved.end_timestamp is None)
        retrieved.end_timestamp = date_utils.get_datetime_utc_now()
        updated = LiveAction.add_or_update(retrieved)
        self.assertTrue(updated.end_timestamp == retrieved.end_timestamp)
        # Test delete
        LiveActionModelTest._delete([retrieved])
        try:
            retrieved = LiveAction.get_by_id(saved.id)
        except StackStormDBObjectNotFoundError:
            retrieved = None
        self.assertIsNone(retrieved, 'managed to retrieve after failure.')
Esempio n. 22
0
 def _get_action_exec_db_model(self, action_db, params):
     liveaction_db = LiveActionDB()
     liveaction_db.status = action_constants.LIVEACTION_STATUS_REQUESTED
     liveaction_db.start_timestamp = date_utils.get_datetime_utc_now()
     liveaction_db.action = ResourceReference(
         name=action_db.name,
         pack=action_db.pack).ref
     liveaction_db.parameters = params
     liveaction_db.context = {'user': cfg.CONF.system_user.user}
     return liveaction_db
Esempio n. 23
0
 def _get_failingaction_exec_db_model(self, params):
     liveaction_db = LiveActionDB()
     liveaction_db.status = action_constants.LIVEACTION_STATUS_REQUESTED
     liveaction_db.start_timestamp = datetime.datetime.now()
     liveaction_db.action = ResourceReference(
         name=RunnerContainerTest.failingaction_db.name,
         pack=RunnerContainerTest.failingaction_db.pack).ref
     liveaction_db.parameters = params
     liveaction_db.context = {'user': cfg.CONF.system_user.user}
     return liveaction_db
Esempio n. 24
0
 def test_chain_runner_success_task_action_call_with_no_params(
         self, request):
     # Make sure that the runner doesn't explode if task definition contains
     # no "params" section
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_ACTION_CALL_NO_PARAMS_PATH
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(name=ACTION_1.name,
                                                        pack=ACTION_1.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.liveaction.notify = CHAIN_NOTIFY_DB
     chain_runner.pre_run()
     chain_runner.run({})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     # based on the chain the callcount is known to be 3. Not great but works.
     self.assertEqual(request.call_count, 3)
Esempio n. 25
0
 def test_chain_runner_no_default(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_NO_DEFAULT
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(name=ACTION_1.name,
                                                        pack=ACTION_1.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.pre_run()
     chain_runner.run({})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     # In case of this chain default_node is the first_node.
     default_node = chain_runner.chain_holder.actionchain.default
     first_node = chain_runner.chain_holder.actionchain.chain[0]
     self.assertEqual(default_node, first_node.name)
     # based on the chain the callcount is known to be 3. Not great but works.
     self.assertEqual(request.call_count, 3)
Esempio n. 26
0
    def test_cancel_retry(self):
        liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS)
        liveaction, execution = action_service.request(liveaction)
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status, action_constants.LIVEACTION_STATUS_RUNNING)

        mistral_context = liveaction.context.get('mistral', None)
        self.assertIsNotNone(mistral_context)
        self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id'))
        self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name'))

        requester = cfg.CONF.system_user.user
        liveaction, execution = action_service.request_cancellation(liveaction, requester)
        executions.ExecutionManager.update.assert_called_with(WF1_EXEC.get('id'), 'CANCELLED')
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status, action_constants.LIVEACTION_STATUS_CANCELING)
Esempio n. 27
0
    def test_launch_workflow_reverse(self):
        # no differences for liveaction (direct == reverse)
        liveaction = LiveActionDB(action=WF3_NAME, parameters=ACTION_PARAMS)
        liveaction, execution = action_service.request(liveaction)
        liveaction = self._wait_on_status(
            liveaction, action_constants.LIVEACTION_STATUS_RUNNING)

        # no differences for mistral_context (direct == reverse)
        mistral_context = liveaction.context.get('mistral', None)
        self.assertIsNotNone(mistral_context)
        self.assertEqual(mistral_context['execution_id'], WF3_EXEC.get('id'))
        self.assertEqual(mistral_context['workflow_name'],
                         WF3_EXEC.get('workflow_name'))

        # no differences for workflow_input (direct == reverse)
        workflow_input = copy.deepcopy(ACTION_PARAMS)
        workflow_input.update({'count': '3'})

        env = {
            'st2_execution_id': str(execution.id),
            'st2_liveaction_id': str(liveaction.id),
            'st2_action_api_url': 'http://0.0.0.0:9101/v1',
            '__actions': {
                'st2.action': {
                    'st2_context': {
                        'api_url': 'http://0.0.0.0:9101/v1',
                        'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions',
                        'parent': {
                            'pack': 'mistral_tests',
                            'execution_id': str(execution.id)
                        },
                        'notify': {},
                        'skip_notify_tasks': []
                    }
                }
            }
        }

        # task_name must be passed to mistral.executions.create for reverse workflows
        task_name = WF3_REVERSE_TARGET_TASK_NAME

        executions.ExecutionManager.create.assert_called_with(
            WF3_NAME,
            workflow_input=workflow_input,
            env=env,
            notify=NOTIFY,
            task_name=task_name)
Esempio n. 28
0
    def test_launch_workflow_with_mistral_auth(self):
        cfg.CONF.set_default('keystone_username', 'foo', group='mistral')
        cfg.CONF.set_default('keystone_password', 'bar', group='mistral')
        cfg.CONF.set_default('keystone_project_name', 'admin', group='mistral')
        cfg.CONF.set_default('keystone_auth_url', 'http://localhost:5000/v3', group='mistral')

        MistralRunner.entry_point = mock.PropertyMock(return_value=WF1_YAML_FILE_PATH)
        liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS)
        liveaction, execution = action_service.request(liveaction)
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status, action_constants.LIVEACTION_STATUS_RUNNING)

        mistral_context = liveaction.context.get('mistral', None)
        self.assertIsNotNone(mistral_context)
        self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id'))
        self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name'))

        workflow_input = copy.deepcopy(ACTION_PARAMS)
        workflow_input.update({'count': '3'})

        env = {
            'st2_execution_id': str(execution.id),
            'st2_liveaction_id': str(liveaction.id),
            '__actions': {
                'st2.action': {
                    'st2_context': {
                        'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions',
                        'parent': {
                            'execution_id': str(execution.id)
                        },
                        'notify': {},
                        'skip_notify_tasks': []
                    }
                }
            }
        }

        client.Client.authenticate.assert_called_with(
            cfg.CONF.mistral.v2_base_url,
            cfg.CONF.mistral.keystone_username,
            cfg.CONF.mistral.keystone_password,
            cfg.CONF.mistral.keystone_project_name,
            cfg.CONF.mistral.keystone_auth_url,
            None, 'publicURL', 'workflow', None, None, None)

        executions.ExecutionManager.create.assert_called_with(
            WF1_NAME, workflow_input=workflow_input, env=env)
Esempio n. 29
0
    def _schedule_execution(self, action_alias_db, params, notify, context,
                            requester_user, show_secrets):
        action_ref = action_alias_db.action_ref
        action_db = action_utils.get_action_by_ref(action_ref)

        if not action_db:
            raise StackStormDBObjectNotFoundError(
                'Action with ref "%s" not found ' % (action_ref))

        assert_user_has_resource_db_permission(
            user_db=requester_user,
            resource_db=action_db,
            permission_type=PermissionType.ACTION_EXECUTE)

        try:
            # prior to shipping off the params cast them to the right type.
            params = action_param_utils.cast_params(
                action_ref=action_alias_db.action_ref,
                params=params,
                cast_overrides=CAST_OVERRIDES)
            if not context:
                context = {
                    'action_alias_ref':
                    reference.get_ref_from_model(action_alias_db),
                    'user':
                    get_system_username()
                }
            liveaction = LiveActionDB(action=action_alias_db.action_ref,
                                      context=context,
                                      parameters=params,
                                      notify=notify)
            _, action_execution_db = action_service.request(liveaction)
            mask_secrets = self._get_mask_secrets(requester_user,
                                                  show_secrets=show_secrets)
            return ActionExecutionAPI.from_model(action_execution_db,
                                                 mask_secrets=mask_secrets)
        except ValueError as e:
            LOG.exception('Unable to execute action.')
            abort(http_client.BAD_REQUEST, str(e))
        except jsonschema.ValidationError as e:
            LOG.exception(
                'Unable to execute action. Parameter validation failed.')
            abort(http_client.BAD_REQUEST, str(e))
        except Exception as e:
            LOG.exception(
                'Unable to execute action. Unexpected error encountered.')
            abort(http_client.INTERNAL_SERVER_ERROR, str(e))
Esempio n. 30
0
    def test_notify_triggers(self):
        liveaction_db = LiveActionDB(action='core.local')
        liveaction_db.id = bson.ObjectId()
        liveaction_db.description = ''
        liveaction_db.status = 'succeeded'
        liveaction_db.parameters = {}
        on_success = NotificationSubSchema(message='Action succeeded.')
        on_failure = NotificationSubSchema(message='Action failed.')
        liveaction_db.notify = NotificationSchema(on_success=on_success,
                                                  on_failure=on_failure)
        liveaction_db.start_timestamp = date_utils.get_datetime_utc_now()
        liveaction_db.end_timestamp = \
            (liveaction_db.start_timestamp + datetime.timedelta(seconds=50))
        LiveAction.add_or_update(liveaction_db)

        execution = MOCK_EXECUTION
        execution.liveaction = vars(LiveActionAPI.from_model(liveaction_db))
        execution.status = liveaction_db.status

        dispatcher = NotifierTestCase.MockDispatcher(self)
        notifier = Notifier(connection=None, queues=[], trigger_dispatcher=dispatcher)
        notifier.process(execution)
    def test_chain_runner_success_path(self, request):
        chain_runner = acr.get_runner()
        chain_runner.entry_point = CHAIN_1_PATH
        chain_runner.action = ACTION_1
        action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
        chain_runner.liveaction = LiveActionDB(action=action_ref)
        chain_runner.pre_run()
        chain_runner.run({})
        self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
        self.assertEqual(request.call_count, 2)
        first_call_args = request.call_args_list[0][0]
        liveaction_db = first_call_args[0]
        self.assertTrue(liveaction_db.notify, 'Notify property expected.')

        second_call_args = request.call_args_list[1][0]
        liveaction_db = second_call_args[0]
        self.assertFalse(liveaction_db.notify, 'Notify property not expected.')
Esempio n. 32
0
 def _get_output_schema_exec_db_model(self, params):
     status = action_constants.LIVEACTION_STATUS_REQUESTED
     start_timestamp = date_utils.get_datetime_utc_now()
     action_ref = ResourceReference(
         name=RunnerContainerTest.schema_output_action_db.name,
         pack=RunnerContainerTest.schema_output_action_db.pack,
     ).ref
     parameters = params
     context = {"user": cfg.CONF.system_user.user}
     liveaction_db = LiveActionDB(
         status=status,
         start_timestamp=start_timestamp,
         action=action_ref,
         parameters=parameters,
         context=context,
     )
     return liveaction_db
Esempio n. 33
0
    def test_failed_cancel(self):
        liveaction = LiveActionDB(action='executions.local',
                                  parameters={'cmd': 'uname -a'})
        liveaction, _ = action_service.request(liveaction)
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)

        # Cancel execution.
        action_service.request_cancellation(liveaction,
                                            cfg.CONF.system_user.user)

        # Cancellation failed and execution state remains "canceling".
        ActionRunner.cancel.assert_called_once_with()
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status,
                         action_constants.LIVEACTION_STATUS_CANCELING)
Esempio n. 34
0
    def test_launch_workflow_under_parent_chain_with_nonetype_in_params_context(
            self):
        ac_ctx = {'chain': {'params': None}}

        liveaction = LiveActionDB(action=WF1_NAME,
                                  parameters=ACTION_PARAMS,
                                  context=ac_ctx)
        liveaction, execution = action_service.request(liveaction)
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)

        mistral_context = liveaction.context.get('mistral', None)
        self.assertIsNotNone(mistral_context)
        self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id'))
        self.assertEqual(mistral_context['workflow_name'],
                         WF1_EXEC.get('workflow_name'))

        workflow_input = copy.deepcopy(ACTION_PARAMS)
        workflow_input.update({'count': '3'})

        env = {
            'st2_execution_id': str(execution.id),
            'st2_liveaction_id': str(liveaction.id),
            'st2_action_api_url': 'http://0.0.0.0:9101/v1',
            '__actions': {
                'st2.action': {
                    'st2_context': {
                        'api_url': 'http://0.0.0.0:9101/v1',
                        'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions',
                        'parent': {
                            'pack': 'mistral_tests',
                            'execution_id': str(execution.id),
                            'chain': {
                                'params': None
                            }
                        },
                        'notify': {},
                        'skip_notify_tasks': []
                    }
                }
            }
        }

        executions.ExecutionManager.create.assert_called_with(
            WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY)
Esempio n. 35
0
    def test_chain_pause_resume_status_change(self):
        # Tests context_result is updated when last task's status changes between pause and resume

        action = TEST_PACK + '.' + 'test_pause_resume_context_result'
        liveaction = LiveActionDB(action=action)
        liveaction, execution = action_service.request(liveaction)
        liveaction = LiveAction.get_by_id(str(liveaction.id))

        # Wait until the liveaction is paused.
        liveaction = self._wait_for_status(
            liveaction, action_constants.LIVEACTION_STATUS_PAUSED)
        extra_info = str(liveaction)
        self.assertEqual(liveaction.status,
                         action_constants.LIVEACTION_STATUS_PAUSED, extra_info)

        # Wait for non-blocking threads to complete. Ensure runner is not running.
        MockLiveActionPublisherNonBlocking.wait_all()

        last_task_liveaction_id = liveaction.result['tasks'][-1][
            'liveaction_id']

        action_utils.update_liveaction_status(
            status=action_constants.LIVEACTION_STATUS_SUCCEEDED,
            end_timestamp=date_utils.get_datetime_utc_now(),
            result={'foo': 'bar'},
            liveaction_id=last_task_liveaction_id)

        # Request action chain to resume.
        liveaction, execution = action_service.request_resume(
            liveaction, USERNAME)

        # Wait until the liveaction is completed.
        liveaction = self._wait_for_status(
            liveaction, action_constants.LIVEACTION_STATUS_SUCCEEDED)

        self.assertEqual(liveaction.status,
                         action_constants.LIVEACTION_STATUS_SUCCEEDED,
                         str(liveaction))

        # Wait for non-blocking threads to complete.
        MockLiveActionPublisherNonBlocking.wait_all()

        # Check liveaction result.
        self.assertIn('tasks', liveaction.result)
        self.assertEqual(len(liveaction.result['tasks']), 2)
        self.assertEqual(liveaction.result['tasks'][0]['result']['foo'], 'bar')
Esempio n. 36
0
 def test_chain_runner_dependent_param_temp(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_DEP_INPUT
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.pre_run()
     chain_runner.run({'s1': 1, 's2': 2, 's3': 3, 's4': 4})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     expected_values = [{u'p1': u'1'},
                        {u'p1': u'1'},
                        {u'p2': u'1', u'p3': u'1', u'p1': u'1'}]
     # Each of the call_args must be one of
     for call_args in request.call_args_list:
         self.assertIn(call_args[0][0].parameters, expected_values)
         expected_values.remove(call_args[0][0].parameters)
     self.assertEqual(len(expected_values), 0, 'Not all expected values received.')
Esempio n. 37
0
 def test_chain_runner_dependent_param_temp(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_DEP_INPUT
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(
         name=ACTION_1.name, pack=ACTION_1.pack
     )
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.pre_run()
     chain_runner.run({"s1": 1, "s2": 2, "s3": 3, "s4": 4})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     expected_values = [{"p1": "1"}, {"p1": "1"}, {"p2": "1", "p3": "1", "p1": "1"}]
     # Each of the call_args must be one of
     for call_args in request.call_args_list:
         self.assertIn(call_args[0][0].parameters, expected_values)
         expected_values.remove(call_args[0][0].parameters)
     self.assertEqual(len(expected_values), 0, "Not all expected values received.")
Esempio n. 38
0
    def test_cancel(self):
        MistralRunner.entry_point = mock.PropertyMock(return_value=WF1_YAML_FILE_PATH)
        liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS)
        liveaction, execution = action_service.request(liveaction)
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status, action_constants.LIVEACTION_STATUS_RUNNING)

        mistral_context = liveaction.context.get('mistral', None)
        self.assertIsNotNone(mistral_context)
        self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id'))
        self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name'))

        requester = cfg.CONF.system_user.user
        liveaction, execution = action_service.request_cancellation(liveaction, requester)
        executions.ExecutionManager.update.assert_called_with(WF1_EXEC.get('id'), 'PAUSED')
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status, action_constants.LIVEACTION_STATUS_CANCELED)
Esempio n. 39
0
    def test_callback(self):
        liveaction = LiveActionDB(
            action='core.local', parameters={'cmd': 'uname -a'},
            callback={
                'source': 'mistral',
                'url': 'http://127.0.0.1:8989/v2/action_executions/12345'
            }
        )

        for status in action_constants.LIVEACTION_COMPLETED_STATES:
            expected_mistral_status = mistral_status_map[status]
            LocalShellRunner.run = mock.Mock(return_value=(status, NON_EMPTY_RESULT, None))
            liveaction, execution = action_service.request(liveaction)
            liveaction = LiveAction.get_by_id(str(liveaction.id))
            self.assertEqual(liveaction.status, status)
            action_executions.ActionExecutionManager.update.assert_called_with(
                '12345', state=expected_mistral_status, output=NON_EMPTY_RESULT)
Esempio n. 40
0
    def test_action_chain_runner_referenced_action_doesnt_exist(self, mock_request):
        # Action referenced by a task doesn't exist, should result in a top level error
        chain_runner = acr.get_runner()
        chain_runner.entry_point = CHAIN_WITH_INVALID_ACTION
        chain_runner.action = ACTION_2
        action_ref = ResourceReference.to_string_reference(name=ACTION_2.name, pack=ACTION_2.pack)
        chain_runner.liveaction = LiveActionDB(action=action_ref)
        chain_runner.pre_run()

        action_parameters = {}
        status, output, _ = chain_runner.run(action_parameters=action_parameters)

        expected_error = ('Failed to run task "c1". Action with reference "wolfpack.a2" '
                          'doesn\'t exist.')
        self.assertEqual(status, LIVEACTION_STATUS_FAILED)
        self.assertIn(expected_error, output['error'])
        self.assertIn('Traceback', output['traceback'])
Esempio n. 41
0
    def test_callback_incomplete_state(self):
        local_runner_cls = self.get_runner_class('local_runner')
        local_run_result = (action_constants.LIVEACTION_STATUS_RUNNING, NON_EMPTY_RESULT, None)
        local_runner_cls.run = mock.Mock(return_value=local_run_result)

        liveaction = LiveActionDB(
            action='core.local', parameters={'cmd': 'uname -a'},
            callback={
                'source': MISTRAL_RUNNER_NAME,
                'url': 'http://127.0.0.1:8989/v2/action_executions/12345'
            }
        )

        liveaction, execution = action_service.request(liveaction)
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status, action_constants.LIVEACTION_STATUS_RUNNING)
        self.assertFalse(action_executions.ActionExecutionManager.update.called)
Esempio n. 42
0
    def test_notify_triggers(self):
        liveaction = LiveActionDB(action='core.local')
        liveaction.description = ''
        liveaction.status = 'succeeded'
        liveaction.parameters = {}
        on_success = NotificationSubSchema(message='Action succeeded.')
        on_failure = NotificationSubSchema(message='Action failed.')
        liveaction.notify = NotificationSchema(on_success=on_success,
                                               on_failure=on_failure)
        liveaction.start_timestamp = date_utils.get_datetime_utc_now()
        liveaction.end_timestamp = liveaction.start_timestamp + datetime.timedelta(seconds=50)

        dispatcher = NotifierTestCase.MockDispatcher(self)
        notifier = Notifier(connection=None, queues=[], trigger_dispatcher=dispatcher)
        notifier.process(liveaction)
Esempio n. 43
0
    def test_chain_cancel(self):
        # A temp file is created during test setup. Ensure the temp file exists.
        # The test action chain will stall until this file is deleted. This gives
        # the unit test a moment to run any test related logic.
        path = self.temp_file_path
        self.assertTrue(os.path.exists(path))

        action = TEST_PACK + '.' + 'test_cancel'
        params = {'tempfile': path, 'message': 'foobar'}
        liveaction = LiveActionDB(action=action, parameters=params)
        liveaction, execution = action_service.request(liveaction)
        liveaction = LiveAction.get_by_id(str(liveaction.id))

        # Wait until the liveaction is running.
        liveaction = self._wait_for_status(
            liveaction, action_constants.LIVEACTION_STATUS_RUNNING)
        self.assertEqual(liveaction.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)

        # Request action chain to cancel.
        liveaction, execution = action_service.request_cancellation(
            liveaction, USERNAME)

        # Wait until the liveaction is canceling.
        liveaction = self._wait_for_status(
            liveaction, action_constants.LIVEACTION_STATUS_CANCELING)
        self.assertEqual(liveaction.status,
                         action_constants.LIVEACTION_STATUS_CANCELING)

        # Delete the temporary file that the action chain is waiting on.
        os.remove(path)
        self.assertFalse(os.path.exists(path))

        # Wait until the liveaction is canceled.
        liveaction = self._wait_for_status(
            liveaction, action_constants.LIVEACTION_STATUS_CANCELED)
        self.assertEqual(liveaction.status,
                         action_constants.LIVEACTION_STATUS_CANCELED)

        # Wait for non-blocking threads to complete. Ensure runner is not running.
        MockLiveActionPublisherNonBlocking.wait_all()

        # Check liveaction result.
        self.assertIn('tasks', liveaction.result)
        self.assertEqual(len(liveaction.result['tasks']), 1)
Esempio n. 44
0
    def test_notify_triggers(self):
        liveaction = LiveActionDB(action='core.local')
        liveaction.description = ''
        liveaction.status = 'succeeded'
        liveaction.parameters = {}
        on_success = NotificationSubSchema(message='Action succeeded.')
        on_failure = NotificationSubSchema(message='Action failed.')
        liveaction.notify = NotificationSchema(on_success=on_success,
                                               on_failure=on_failure)
        liveaction.start_timestamp = date_utils.get_datetime_utc_now()

        dispatcher = NotifierTestCase.MockDispatcher(self)
        notifier = Notifier(connection=None,
                            queues=[],
                            trigger_dispatcher=dispatcher)
        notifier.process(liveaction)
Esempio n. 45
0
    def _re_run_live_action(self, live_action_db):
        retry_count = self._get_live_action_retry_count(live_action_db=live_action_db)

        # Add additional policy specific info to the context
        context = getattr(live_action_db, 'context', {})
        new_context = copy.deepcopy(context)
        new_context['policies'] = {}
        new_context['policies']['retry'] = {
            'applied_policy': self._policy_ref,
            'retry_count': (retry_count + 1),
            'retried_liveaction_id': str(live_action_db.id)
        }
        action_ref = live_action_db.action
        parameters = live_action_db.parameters
        new_live_action_db = LiveActionDB(action=action_ref, parameters=parameters,
                                          context=new_context)
        _, action_execution_db = action_services.request(new_live_action_db)
        return action_execution_db
Esempio n. 46
0
    def test_update_canceled_liveaction(self):
        liveaction_db = LiveActionDB()
        liveaction_db.status = 'initializing'
        liveaction_db.start_timestamp = get_datetime_utc_now()
        liveaction_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
        }
        liveaction_db.parameters = params
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        origliveaction_db = copy.copy(liveaction_db)

        # Update by id.
        newliveaction_db = action_db_utils.update_liveaction_status(
            status='running', liveaction_id=liveaction_db.id)

        # Verify id didn't change.
        self.assertEqual(origliveaction_db.id, newliveaction_db.id)
        self.assertEqual(newliveaction_db.status, 'running')

        # Verify that state is published.
        self.assertTrue(LiveActionPublisher.publish_state.called)
        LiveActionPublisher.publish_state.assert_called_once_with(newliveaction_db, 'running')

        # Cancel liveaction.
        now = get_datetime_utc_now()
        status = 'canceled'
        newliveaction_db = action_db_utils.update_liveaction_status(
            status=status, end_timestamp=now, liveaction_id=liveaction_db.id)
        self.assertEqual(origliveaction_db.id, newliveaction_db.id)
        self.assertEqual(newliveaction_db.status, status)
        self.assertEqual(newliveaction_db.end_timestamp, now)

        # Since liveaction has already been canceled, check that anymore update of
        # status, result, context, and end timestamp are not processed.
        now = get_datetime_utc_now()
        status = 'succeeded'
        result = 'Work is done.'
        context = {'third_party_id': uuid.uuid4().hex}
        newliveaction_db = action_db_utils.update_liveaction_status(
            status=status, result=result, context=context, end_timestamp=now,
            liveaction_id=liveaction_db.id)

        self.assertEqual(origliveaction_db.id, newliveaction_db.id)
        self.assertEqual(newliveaction_db.status, 'canceled')
        self.assertNotEqual(newliveaction_db.result, result)
        self.assertNotEqual(newliveaction_db.context, context)
        self.assertNotEqual(newliveaction_db.end_timestamp, now)
Esempio n. 47
0
    def test_callback_retry_exhausted(self):
        liveaction = LiveActionDB(
            action='core.local', parameters={'cmd': 'uname -a'},
            callback={
                'source': 'mistral',
                'url': 'http://127.0.0.1:8989/v2/action_executions/12345'
            }
        )

        liveaction, execution = action_service.request(liveaction)
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status, action_constants.LIVEACTION_STATUS_SUCCEEDED)

        # This test initially setup mock for action_executions.ActionExecutionManager.update
        # to fail the first 4 times and return success on the 5th times. The max attempts
        # is set to 3. We expect only 3 calls to pass thru the update method.
        calls = [call('12345', state='SUCCESS', output=NON_EMPTY_RESULT) for i in range(0, 2)]
        action_executions.ActionExecutionManager.update.assert_has_calls(calls)
Esempio n. 48
0
    def test_chain_runner_failure_during_param_rendering_single_task(self, request):
        # Parameter rendering should result in a top level error which aborts
        # the whole chain
        chain_runner = acr.get_runner()
        chain_runner.entry_point = CHAIN_FIRST_TASK_RENDER_FAIL_PATH
        chain_runner.action = ACTION_1
        action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
        chain_runner.liveaction = LiveActionDB(action=action_ref)
        chain_runner.pre_run()
        status, result, _ = chain_runner.run({})

        # No tasks ran because rendering of parameters for the first task failed
        self.assertEqual(status, LIVEACTION_STATUS_FAILED)
        self.assertEqual(result['tasks'], [])
        self.assertIn('error', result)
        self.assertIn('traceback', result)
        self.assertIn('Failed to run task "c1". Parameter rendering failed', result['error'])
        self.assertIn('Traceback', result['traceback'])
Esempio n. 49
0
 def test_chain_runner_no_default_multiple_options(self, request):
     # subtle difference is that when there are multiple possible default nodes
     # the order per chain definition may not be preseved. This is really a
     # poorly formatted chain but we still the best attempt to work.
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_NO_DEFAULT_2
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.pre_run()
     chain_runner.run({})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     # In case of this chain default_node is the first_node.
     default_node = chain_runner.chain_holder.actionchain.default
     first_node = chain_runner.chain_holder.actionchain.chain[0]
     self.assertEqual(default_node, first_node.name)
     # based on the chain the callcount is known to be 2.
     self.assertEqual(request.call_count, 2)
Esempio n. 50
0
    def test_get_all(self):
        resp = stream.StreamController().get_all()
        self.assertEqual(resp._status, '200 OK')
        self.assertIn(('Content-Type', 'text/event-stream; charset=UTF-8'), resp._headerlist)

        listener = st2common.stream.listener.get_listener(name='stream')
        process = listener.processor(LiveActionAPI)

        message = None

        for message in resp._app_iter:
            if message != '\n':
                break
            process(LiveActionDB(**LIVE_ACTION_1), META())

        self.assertIn('event: some__thing', message)
        self.assertIn('data: {"', message)
        self.assertNotIn(SUPER_SECRET_PARAMETER, message)
Esempio n. 51
0
    def test_noop_cancel(self):
        liveaction = LiveActionDB(action='executions.local',
                                  parameters={'cmd': 'uname -a'})
        liveaction, _ = action_service.request(liveaction)
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status,
                         action_constants.LIVEACTION_STATUS_REQUESTED)

        # Cancel execution.
        action_service.request_cancellation(liveaction,
                                            cfg.CONF.system_user.user)

        # Cancel is only called when liveaction is still in running state.
        # Otherwise, the cancellation is only a state change.
        self.assertFalse(ActionRunner.cancel.called)
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(liveaction.status,
                         action_constants.LIVEACTION_STATUS_CANCELED)
Esempio n. 52
0
 def test_chain_runner_typed_params(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_TYPED_PARAMS
     chain_runner.action = ACTION_2
     action_ref = ResourceReference.to_string_reference(name=ACTION_2.name, pack=ACTION_2.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.pre_run()
     chain_runner.run({'s1': 1, 's2': 'two', 's3': 3.14})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     expected_value = {'booltype': True,
                       'inttype': 1,
                       'numbertype': 3.14,
                       'strtype': 'two',
                       'arrtype': ['1', 'two'],
                       'objtype': {'s2': 'two',
                                   'k1': '1'}}
     mock_args, _ = request.call_args
     self.assertEqual(mock_args[0].parameters, expected_value)
Esempio n. 53
0
    def _create_nested_executions(self, depth=2):
        """Utility function for easily creating nested LiveAction and ActionExecutions for testing

        returns (childmost_liveaction_db, parentmost_liveaction_db)
        """

        if depth <= 0:
            raise Exception("Please provide a depth > 0")

        root_liveaction_db = LiveActionDB()
        root_liveaction_db.status = action_constants.LIVEACTION_STATUS_PAUSED
        root_liveaction_db.action = ACTION_WORKFLOW_REF
        root_liveaction_db = LiveAction.add_or_update(root_liveaction_db)
        root_ex = executions.create_execution_object(root_liveaction_db)

        last_id = root_ex['id']

        # Create children to the specified depth
        for i in range(depth):

            # Childmost liveaction should use ACTION_REF, everything else
            # should use ACTION_WORKFLOW_REF
            if i == depth:
                action = ACTION_REF
            else:
                action = ACTION_WORKFLOW_REF

            child_liveaction_db = LiveActionDB()
            child_liveaction_db.status = action_constants.LIVEACTION_STATUS_PAUSED
            child_liveaction_db.action = action
            child_liveaction_db.context = {"parent": {"execution_id": last_id}}
            child_liveaction_db = LiveAction.add_or_update(child_liveaction_db)
            parent_ex = executions.create_execution_object(child_liveaction_db)
            last_id = parent_ex.id

        # Return the last-created child as well as the root
        return (child_liveaction_db, root_liveaction_db)
Esempio n. 54
0
 def test_chain_runner_dependent_results_param(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_DEP_RESULTS_INPUT
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.pre_run()
     chain_runner.run({'s1': 1})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     expected_values = [{u'p1': u'1'},
                        {u'p1': u'1'},
                        {u'out': u"{'c2': {'o1': '1'}, 'c1': {'o1': '1'}}"}]
     # Each of the call_args must be one of
     self.assertEqual(request.call_count, 3)
     for call_args in request.call_args_list:
         self.assertTrue(call_args[0][0].parameters in expected_values)
         expected_values.remove(call_args[0][0].parameters)
     self.assertEqual(len(expected_values), 0, 'Not all expected values received.')
Esempio n. 55
0
    def test_notify_triggers(self):
        liveaction_db = LiveActionDB(action='core.local')
        liveaction_db.id = bson.ObjectId()
        liveaction_db.description = ''
        liveaction_db.status = 'succeeded'
        liveaction_db.parameters = {}
        on_success = NotificationSubSchema(message='Action succeeded.')
        on_failure = NotificationSubSchema(message='Action failed.')
        liveaction_db.notify = NotificationSchema(on_success=on_success,
                                                  on_failure=on_failure)
        liveaction_db.start_timestamp = date_utils.get_datetime_utc_now()
        liveaction_db.end_timestamp = \
            (liveaction_db.start_timestamp + datetime.timedelta(seconds=50))
        LiveAction.add_or_update(liveaction_db)

        execution = MOCK_EXECUTION
        execution.liveaction = vars(LiveActionAPI.from_model(liveaction_db))
        execution.status = liveaction_db.status

        dispatcher = NotifierTestCase.MockDispatcher(self)
        notifier = Notifier(connection=None, queues=[], trigger_dispatcher=dispatcher)
        notifier.process(execution)
Esempio n. 56
0
 def test_liveaction_create_with_notify_both_on_success_and_on_error(self):
     created = LiveActionDB()
     created.action = 'core.local'
     created.description = ''
     created.status = 'running'
     created.parameters = {}
     on_success = NotificationSubSchema(message='Action succeeded.')
     on_failure = NotificationSubSchema(message='Action failed.')
     created.notify = NotificationSchema(on_success=on_success,
                                         on_failure=on_failure)
     saved = LiveActionModelTest._save_liveaction(created)
     retrieved = LiveAction.get_by_id(saved.id)
     self.assertEqual(saved.action, retrieved.action,
                      'Same triggertype was not returned.')
     # Assert notify settings saved are right.
     self.assertEqual(on_success.message, retrieved.notify.on_success.message)
     self.assertEqual(on_failure.message, retrieved.notify.on_failure.message)
     self.assertEqual(retrieved.notify.on_complete, None)
Esempio n. 57
0
    def test_update_liveaction_with_incorrect_output_schema(self):
        liveaction_db = LiveActionDB()
        liveaction_db.status = 'initializing'
        liveaction_db.start_timestamp = get_datetime_utc_now()
        liveaction_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
        }
        liveaction_db.parameters = params
        runner = mock.MagicMock()
        runner.output_schema = {
            "notaparam": {
                "type": "boolean"
            }
        }
        liveaction_db.runner = runner
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        origliveaction_db = copy.copy(liveaction_db)

        now = get_datetime_utc_now()
        status = 'succeeded'
        result = 'Work is done.'
        context = {'third_party_id': uuid.uuid4().hex}
        newliveaction_db = action_db_utils.update_liveaction_status(
            status=status, result=result, context=context, end_timestamp=now,
            liveaction_id=liveaction_db.id)

        self.assertEqual(origliveaction_db.id, newliveaction_db.id)
        self.assertEqual(newliveaction_db.status, status)
        self.assertEqual(newliveaction_db.result, result)
        self.assertDictEqual(newliveaction_db.context, context)
        self.assertEqual(newliveaction_db.end_timestamp, now)
Esempio n. 58
0
MOCK_TRIGGER_INSTANCE = TriggerInstanceDB()
MOCK_TRIGGER_INSTANCE.id = 'triggerinstance-test'
MOCK_TRIGGER_INSTANCE.payload = {'t1_p': 't1_p_v'}
MOCK_TRIGGER_INSTANCE.occurrence_time = date_utils.get_datetime_utc_now()

MOCK_TRIGGER_INSTANCE_2 = TriggerInstanceDB()
MOCK_TRIGGER_INSTANCE_2.id = 'triggerinstance-test2'
MOCK_TRIGGER_INSTANCE_2.payload = {'t1_p': None}
MOCK_TRIGGER_INSTANCE_2.occurrence_time = date_utils.get_datetime_utc_now()

MOCK_TRIGGER_INSTANCE_3 = TriggerInstanceDB()
MOCK_TRIGGER_INSTANCE_3.id = 'triggerinstance-test3'
MOCK_TRIGGER_INSTANCE_3.payload = {'t1_p': None, 't2_p': 'value2'}
MOCK_TRIGGER_INSTANCE_3.occurrence_time = date_utils.get_datetime_utc_now()

MOCK_LIVEACTION = LiveActionDB()
MOCK_LIVEACTION.id = 'liveaction-test-1.id'
MOCK_LIVEACTION.status = 'requested'

MOCK_EXECUTION = ActionExecutionDB()
MOCK_EXECUTION.id = 'exec-test-1.id'
MOCK_EXECUTION.status = 'requested'

FAILURE_REASON = "fail!"


class EnforceTest(DbTestCase):

    models = None

    @classmethod