Пример #1
0
 def test_get_runner_module_fail(self):
     runnertype_db = RunnerTypeDB()
     runnertype_db.runner_module = 'absent.module'
     runner = None
     try:
         runner = get_runner(runnertype_db.runner_module)
     except ActionRunnerCreateError:
         pass
     self.assertFalse(runner, 'TestRunner must be valid.')
Пример #2
0
 def test_get_runner_module_fail(self):
     runnertype_db = RunnerTypeDB()
     runnertype_db.runner_module = 'absent.module'
     runner = None
     try:
         runner = get_runner(runnertype_db.runner_module)
     except ActionRunnerCreateError:
         pass
     self.assertFalse(runner, 'TestRunner must be valid.')
Пример #3
0
 def test_get_runner_module_fail(self):
     runnertype_db = RunnerTypeDB(name="dummy",
                                  runner_module="absent.module")
     runner = None
     try:
         runner = get_runner(runnertype_db.runner_module,
                             runnertype_db.runner_module)
     except ActionRunnerCreateError:
         pass
     self.assertFalse(runner, "TestRunner must be valid.")
Пример #4
0
 def _create_save_runnertype(metadata=False):
     created = RunnerTypeDB(name='python')
     created.description = ''
     created.enabled = True
     if not metadata:
         created.runner_parameters = {'r1': None, 'r2': None}
     else:
         created.runner_parameters = {
             'r1': {'type': 'object', 'properties': {'r1a': {'type': 'string'}}},
             'r2': {'type': 'string', 'required': True}
         }
     created.runner_module = 'nomodule'
     return RunnerType.add_or_update(created)
Пример #5
0
 def _create_save_runnertype(metadata=False):
     created = RunnerTypeDB()
     created.name = 'python'
     created.description = ''
     created.enabled = True
     if not metadata:
         created.runner_parameters = {'r1': None, 'r2': None}
     else:
         created.runner_parameters = {
             'r1': {'type': 'object', 'properties': {'r1a': {'type': 'string'}}},
             'r2': {'type': 'string', 'required': True}
         }
     created.runner_module = 'nomodule'
     return RunnerType.add_or_update(created)
Пример #6
0
 def _create_save_runnertype(metadata=False):
     created = RunnerTypeDB()
     created.name = "python"
     created.description = ""
     created.enabled = True
     if not metadata:
         created.runner_parameters = {"r1": None, "r2": None}
     else:
         created.runner_parameters = {
             "r1": {"type": "object", "properties": {"r1a": {"type": "string"}}},
             "r2": {"type": "string", "required": True},
         }
     created.runner_module = "nomodule"
     return RunnerType.add_or_update(created)
    def test_manipulate_permission_grants_unsupported_resource_type(self):
        # Try to manipulate permissions on an unsupported resource
        role_db = self.roles['custom_role_2']
        resource_db = RunnerTypeDB()
        permission_types = [PermissionType.RULE_ALL]

        expected_msg = 'Permissions cannot be manipulated for a resource of type'
        self.assertRaisesRegexp(ValueError, expected_msg,
                                rbac_services.create_permission_grant_for_resource_db,
                                role_db=role_db, resource_db=resource_db,
                                permission_types=permission_types)

        expected_msg = 'Permissions cannot be manipulated for a resource of type'
        self.assertRaisesRegexp(ValueError, expected_msg,
                                rbac_services.remove_permission_grant_for_resource_db,
                                role_db=role_db, resource_db=resource_db,
                                permission_types=permission_types)
Пример #8
0
 def _create_save_runnertype(metadata=False):
     created = RunnerTypeDB(name="python")
     created.description = ""
     created.enabled = True
     if not metadata:
         created.runner_parameters = {"r1": None, "r2": None}
     else:
         created.runner_parameters = {
             "r1": {
                 "type": "object",
                 "properties": {
                     "r1a": {
                         "type": "string"
                     }
                 }
             },
             "r2": {
                 "type": "string",
                 "required": True
             },
         }
     created.runner_module = "nomodule"
     return RunnerType.add_or_update(created)
Пример #9
0
class NotifierTestCase(CleanDbTestCase):
    class MockDispatcher(object):
        def __init__(self, tester):
            self.tester = tester
            self.notify_trigger = ResourceReference.to_string_reference(
                pack=NOTIFY_TRIGGER_TYPE['pack'],
                name=NOTIFY_TRIGGER_TYPE['name'])
            self.action_trigger = ResourceReference.to_string_reference(
                pack=ACTION_TRIGGER_TYPE['pack'],
                name=ACTION_TRIGGER_TYPE['name'])

        def dispatch(self, *args, **kwargs):
            try:
                self.tester.assertEqual(len(args), 1)
                self.tester.assertTrue('payload' in kwargs)
                payload = kwargs['payload']

                if args[0] == self.notify_trigger:
                    self.tester.assertEqual(payload['status'], 'succeeded')
                    self.tester.assertTrue('execution_id' in payload)
                    self.tester.assertEqual(payload['execution_id'],
                                            str(MOCK_EXECUTION.id))
                    self.tester.assertTrue('start_timestamp' in payload)
                    self.tester.assertTrue('end_timestamp' in payload)
                    self.tester.assertEqual('core.local',
                                            payload['action_ref'])
                    self.tester.assertEqual('Action succeeded.',
                                            payload['message'])
                    self.tester.assertTrue('data' in payload)
                    self.tester.assertTrue('run-local-cmd',
                                           payload['runner_ref'])

                if args[0] == self.action_trigger:
                    self.tester.assertEqual(payload['status'], 'succeeded')
                    self.tester.assertTrue('execution_id' in payload)
                    self.tester.assertEqual(payload['execution_id'],
                                            str(MOCK_EXECUTION.id))
                    self.tester.assertTrue('start_timestamp' in payload)
                    self.tester.assertEqual('core.local',
                                            payload['action_name'])
                    self.tester.assertEqual('core.local',
                                            payload['action_ref'])
                    self.tester.assertTrue('result' in payload)
                    self.tester.assertTrue('parameters' in payload)
                    self.tester.assertTrue('run-local-cmd',
                                           payload['runner_ref'])

            except Exception:
                self.tester.fail('Test failed')

    @mock.patch(
        'st2common.util.action_db.get_action_by_ref',
        mock.MagicMock(
            return_value=ActionDB(pack='core',
                                  name='local',
                                  runner_type={'name': 'run-local-cmd'},
                                  parameters={})))
    @mock.patch(
        'st2common.util.action_db.get_runnertype_by_name',
        mock.MagicMock(
            return_value=RunnerTypeDB(name='foo', runner_parameters={})))
    @mock.patch.object(
        Action, 'get_by_ref',
        mock.MagicMock(return_value={'runner_type': {
            'name': 'run-local-cmd'
        }}))
    @mock.patch.object(Policy, 'query', mock.MagicMock(return_value=[]))
    @mock.patch.object(Notifier, '_get_trace_context',
                       mock.MagicMock(return_value={}))
    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)

    @mock.patch(
        'st2common.util.action_db.get_action_by_ref',
        mock.MagicMock(
            return_value=ActionDB(pack='core',
                                  name='local',
                                  runner_type={'name': 'run-local-cmd'},
                                  parameters={})))
    @mock.patch(
        'st2common.util.action_db.get_runnertype_by_name',
        mock.MagicMock(
            return_value=RunnerTypeDB(name='foo', runner_parameters={})))
    @mock.patch.object(
        Action, 'get_by_ref',
        mock.MagicMock(return_value={'runner_type': {
            'name': 'run-local-cmd'
        }}))
    @mock.patch.object(Policy, 'query', mock.MagicMock(return_value=[]))
    @mock.patch.object(Notifier, '_get_trace_context',
                       mock.MagicMock(return_value={}))
    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)

    @mock.patch(
        'st2common.util.action_db.get_action_by_ref',
        mock.MagicMock(return_value=ActionDB(
            pack='core', name='local', runner_type={'name': 'run-local-cmd'})))
    @mock.patch('st2common.util.action_db.get_runnertype_by_name',
                mock.MagicMock(return_value=RunnerTypeDB(
                    name='foo', runner_parameters={'runner_foo': 'foo'})))
    @mock.patch.object(
        Action, 'get_by_ref',
        mock.MagicMock(return_value={'runner_type': {
            'name': 'run-local-cmd'
        }}))
    @mock.patch.object(Policy, 'query', mock.MagicMock(return_value=[]))
    @mock.patch.object(Notifier, '_post_generic_trigger',
                       mock.MagicMock(return_value=True))
    @mock.patch.object(Notifier, '_get_trace_context',
                       mock.MagicMock(return_value={}))
    @mock.patch('st2common.transport.reactor.TriggerDispatcher.dispatch')
    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': 'run-local-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)
class NotifierTestCase(unittest2.TestCase):

    class MockDispatcher(object):
        def __init__(self, tester):
            self.tester = tester
            self.notify_trigger = ResourceReference.to_string_reference(
                pack=NOTIFY_TRIGGER_TYPE['pack'],
                name=NOTIFY_TRIGGER_TYPE['name'])
            self.action_trigger = ResourceReference.to_string_reference(
                pack=ACTION_TRIGGER_TYPE['pack'],
                name=ACTION_TRIGGER_TYPE['name'])

        def dispatch(self, *args, **kwargs):
            try:
                self.tester.assertEqual(len(args), 1)
                self.tester.assertTrue('payload' in kwargs)
                payload = kwargs['payload']

                if args[0] == self.notify_trigger:
                    self.tester.assertEqual(payload['status'], 'succeeded')
                    self.tester.assertTrue('execution_id' in payload)
                    self.tester.assertEqual(payload['execution_id'], str(MOCK_EXECUTION.id))
                    self.tester.assertTrue('start_timestamp' in payload)
                    self.tester.assertTrue('end_timestamp' in payload)
                    self.tester.assertEqual('core.local', payload['action_ref'])
                    self.tester.assertEqual('Action succeeded.', payload['message'])
                    self.tester.assertTrue('data' in payload)
                    self.tester.assertTrue('run-local-cmd', payload['runner_ref'])

                if args[0] == self.action_trigger:
                    self.tester.assertEqual(payload['status'], 'succeeded')
                    self.tester.assertTrue('execution_id' in payload)
                    self.tester.assertEqual(payload['execution_id'], str(MOCK_EXECUTION.id))
                    self.tester.assertTrue('start_timestamp' in payload)
                    self.tester.assertEqual('core.local', payload['action_name'])
                    self.tester.assertEqual('core.local', payload['action_ref'])
                    self.tester.assertTrue('result' in payload)
                    self.tester.assertTrue('parameters' in payload)
                    self.tester.assertTrue('run-local-cmd', payload['runner_ref'])

            except Exception:
                self.tester.fail('Test failed')

    @mock.patch('st2common.util.action_db.get_action_by_ref', mock.MagicMock(
        return_value=ActionDB(pack='core', name='local', runner_type={'name': 'run-local-cmd'},
                              parameters={})))
    @mock.patch('st2common.util.action_db.get_runnertype_by_name', mock.MagicMock(
        return_value=RunnerTypeDB(runner_parameters={})))
    @mock.patch.object(Action, 'get_by_ref', mock.MagicMock(
        return_value={'runner_type': {'name': 'run-local-cmd'}}))
    @mock.patch.object(Policy, 'query', mock.MagicMock(
        return_value=[]))
    @mock.patch.object(Notifier, '_get_execution_for_liveaction', mock.MagicMock(
        return_value=MOCK_EXECUTION))
    @mock.patch.object(Notifier, '_get_trace_context', mock.MagicMock(return_value={}))
    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)

    @mock.patch('st2common.util.action_db.get_action_by_ref', mock.MagicMock(
        return_value=ActionDB(pack='core', name='local', runner_type={'name': 'run-local-cmd'})))
    @mock.patch('st2common.util.action_db.get_runnertype_by_name', mock.MagicMock(
        return_value=RunnerTypeDB(runner_parameters={'runner_foo': 'foo'})))
    @mock.patch.object(Action, 'get_by_ref', mock.MagicMock(
        return_value={'runner_type': {'name': 'run-local-cmd'}}))
    @mock.patch.object(Policy, 'query', mock.MagicMock(
        return_value=[]))
    @mock.patch.object(Notifier, '_get_execution_for_liveaction', mock.MagicMock(
        return_value=MOCK_EXECUTION))
    @mock.patch.object(Notifier, '_post_generic_trigger', mock.MagicMock(
        return_value=True))
    @mock.patch.object(Notifier, '_get_trace_context', mock.MagicMock(return_value={}))
    @mock.patch('st2common.transport.reactor.TriggerDispatcher.dispatch')
    def test_notify_triggers_jinja_patterns(self, dispatch):
        liveaction = LiveActionDB(action='core.local')
        liveaction.description = ''
        liveaction.status = 'succeeded'
        liveaction.parameters = {'cmd': 'mamma mia', 'runner_foo': 'foo'}
        on_success = NotificationSubSchema(message='Command {{action_parameters.cmd}} succeeded.',
                                           data={'stdout': '{{action_results.stdout}}'})
        liveaction.notify = NotificationSchema(on_success=on_success)
        liveaction.start_timestamp = date_utils.get_datetime_utc_now()
        liveaction.end_timestamp = liveaction.start_timestamp + datetime.timedelta(seconds=50)

        notifier = Notifier(connection=None, queues=[])
        notifier.process(liveaction)
        exp = {'status': 'succeeded',
               'start_timestamp': isotime.format(liveaction.start_timestamp),
               'route': 'notify.default', 'runner_ref': 'run-local-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.end_timestamp)}
        dispatch.assert_called_once_with('core.st2.generic.notifytrigger', payload=exp,
                                         trace_context={})
        notifier.process(liveaction)
Пример #11
0
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import jsonschema
import mock
import yaml

import st2actions.bootstrap.actionsregistrar as actions_registrar
from st2common.persistence.action import Action
import st2common.validators.api.action as action_validator
from st2common.models.db.runner import RunnerTypeDB
import st2tests.base as tests_base
import st2tests.fixturesloader as fixtures_loader

MOCK_RUNNER_TYPE_DB = RunnerTypeDB(name='run-local', runner_module='st2.runners.local')


class ActionsRegistrarTest(tests_base.DbTestCase):
    @mock.patch.object(action_validator, '_is_valid_pack', mock.MagicMock(return_value=True))
    @mock.patch.object(action_validator, '_get_runner_model',
                       mock.MagicMock(return_value=MOCK_RUNNER_TYPE_DB))
    def test_register_all_actions(self):
        try:
            packs_base_path = fixtures_loader.get_fixtures_base_path()
            all_actions_in_db = Action.get_all()
            actions_registrar.register_actions(packs_base_paths=[packs_base_path])
        except Exception as e:
            print(str(e))
            self.fail('All actions must be registered without exceptions.')
        else:
Пример #12
0
class NotifierTestCase(unittest2.TestCase):
    class MockDispatcher(object):
        def __init__(self, tester):
            self.tester = tester
            self.notify_trigger = ResourceReference.to_string_reference(
                pack=NOTIFY_TRIGGER_TYPE['pack'],
                name=NOTIFY_TRIGGER_TYPE['name'])
            self.action_trigger = ResourceReference.to_string_reference(
                pack=ACTION_TRIGGER_TYPE['pack'],
                name=ACTION_TRIGGER_TYPE['name'])

        def dispatch(self, *args, **kwargs):
            try:
                self.tester.assertEqual(len(args), 1)
                self.tester.assertTrue('payload' in kwargs)
                payload = kwargs['payload']

                if args[0] == self.notify_trigger:
                    self.tester.assertEqual(payload['status'], 'succeeded')
                    self.tester.assertTrue('execution_id' in payload)
                    self.tester.assertEqual(payload['execution_id'],
                                            MOCK_EXECUTION_ID)
                    self.tester.assertTrue('start_timestamp' in payload)
                    self.tester.assertTrue('end_timestamp' in payload)
                    self.tester.assertEqual('core.local',
                                            payload['action_ref'])
                    self.tester.assertEqual('Action succeeded.',
                                            payload['message'])
                    self.tester.assertTrue('data' in payload)
                    self.tester.assertTrue('run-local-cmd',
                                           payload['runner_ref'])

                if args[0] == self.action_trigger:
                    self.tester.assertEqual(payload['status'], 'succeeded')
                    self.tester.assertTrue('execution_id' in payload)
                    self.tester.assertEqual(payload['execution_id'],
                                            MOCK_EXECUTION_ID)
                    self.tester.assertTrue('start_timestamp' in payload)
                    self.tester.assertEqual('core.local',
                                            payload['action_name'])
                    self.tester.assertEqual('core.local',
                                            payload['action_ref'])
                    self.tester.assertTrue('result' in payload)
                    self.tester.assertTrue('parameters' in payload)
                    self.tester.assertTrue('run-local-cmd',
                                           payload['runner_ref'])

            except Exception:
                self.tester.fail('Test failed')

    @mock.patch(
        'st2common.util.action_db.get_action_by_ref',
        mock.MagicMock(return_value=ActionDB(
            pack='core', name='local', runner_type={'name': 'run-local-cmd'})))
    @mock.patch('st2common.util.action_db.get_runnertype_by_name',
                mock.MagicMock(return_value=RunnerTypeDB(runner_parameters={}))
                )
    @mock.patch.object(
        Action, 'get_by_ref',
        mock.MagicMock(return_value={'runner_type': {
            'name': 'run-local-cmd'
        }}))
    @mock.patch.object(Policy, 'query', mock.MagicMock(return_value=[]))
    @mock.patch.object(Notifier, '_get_execution_id_for_liveaction',
                       mock.MagicMock(return_value=MOCK_EXECUTION_ID))
    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)
Пример #13
0
import six
import jsonschema
import mock
import yaml

import st2common.bootstrap.actionsregistrar as actions_registrar
from st2common.persistence.action import Action
import st2common.validators.api.action as action_validator
from st2common.models.db.runner import RunnerTypeDB

import st2tests.base as tests_base
import st2tests.fixturesloader as fixtures_loader
from st2tests.fixturesloader import get_fixtures_base_path

MOCK_RUNNER_TYPE_DB = RunnerTypeDB(name="run-local", runner_module="st2.runners.local")


# NOTE: We need to perform this patching because test fixtures are located outside of the packs
# base paths directory. This will never happen outside the context of test fixtures.
@mock.patch(
    "st2common.content.utils.get_pack_base_path",
    mock.Mock(return_value=os.path.join(get_fixtures_base_path(), "generic")),
)
class ActionsRegistrarTest(tests_base.DbTestCase):
    @mock.patch.object(
        action_validator, "_is_valid_pack", mock.MagicMock(return_value=True)
    )
    @mock.patch.object(
        action_validator,
        "get_runner_model",
Пример #14
0
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import jsonschema
import mock
import yaml

import st2actions.bootstrap.actionsregistrar as actions_registrar
from st2common.persistence.action import Action
import st2common.validators.api.action as action_validator
from st2common.models.db.runner import RunnerTypeDB
import st2tests.base as tests_base
import st2tests.fixturesloader as fixtures_loader

MOCK_RUNNER_TYPE_DB = RunnerTypeDB()
MOCK_RUNNER_TYPE_DB.name = 'run-local'
MOCK_RUNNER_TYPE_DB.runner_module = 'st2.runners.local'


class ActionsRegistrarTest(tests_base.DbTestCase):
    @mock.patch.object(action_validator, '_is_valid_pack', mock.MagicMock(return_value=True))
    @mock.patch.object(action_validator, '_get_runner_model',
                       mock.MagicMock(return_value=MOCK_RUNNER_TYPE_DB))
    def test_register_all_actions(self):
        try:
            packs_base_path = fixtures_loader.get_fixtures_base_path()
            all_actions_in_db = Action.get_all()
            actions_registrar.register_actions(packs_base_paths=[packs_base_path])
        except Exception as e:
            print(str(e))
Пример #15
0
class NotifierTestCase(CleanDbTestCase):
    class MockDispatcher(object):
        def __init__(self, tester):
            self.tester = tester
            self.notify_trigger = ResourceReference.to_string_reference(
                pack=NOTIFY_TRIGGER_TYPE["pack"],
                name=NOTIFY_TRIGGER_TYPE["name"])
            self.action_trigger = ResourceReference.to_string_reference(
                pack=ACTION_TRIGGER_TYPE["pack"],
                name=ACTION_TRIGGER_TYPE["name"])

        def dispatch(self, *args, **kwargs):
            try:
                self.tester.assertEqual(len(args), 1)
                self.tester.assertTrue("payload" in kwargs)
                payload = kwargs["payload"]

                if args[0] == self.notify_trigger:
                    self.tester.assertEqual(payload["status"], "succeeded")
                    self.tester.assertTrue("execution_id" in payload)
                    self.tester.assertEqual(payload["execution_id"],
                                            str(MOCK_EXECUTION.id))
                    self.tester.assertTrue("start_timestamp" in payload)
                    self.tester.assertTrue("end_timestamp" in payload)
                    self.tester.assertEqual("core.local",
                                            payload["action_ref"])
                    self.tester.assertEqual("Action succeeded.",
                                            payload["message"])
                    self.tester.assertTrue("data" in payload)
                    self.tester.assertTrue("local-shell-cmd",
                                           payload["runner_ref"])

                if args[0] == self.action_trigger:
                    self.tester.assertEqual(payload["status"], "succeeded")
                    self.tester.assertTrue("execution_id" in payload)
                    self.tester.assertEqual(payload["execution_id"],
                                            str(MOCK_EXECUTION.id))
                    self.tester.assertTrue("start_timestamp" in payload)
                    self.tester.assertEqual("core.local",
                                            payload["action_name"])
                    self.tester.assertEqual("core.local",
                                            payload["action_ref"])
                    self.tester.assertTrue("result" in payload)
                    self.tester.assertTrue("parameters" in payload)
                    self.tester.assertTrue("local-shell-cmd",
                                           payload["runner_ref"])

            except Exception:
                self.tester.fail("Test failed")

    @mock.patch(
        "st2common.util.action_db.get_action_by_ref",
        mock.MagicMock(return_value=ActionDB(
            pack="core",
            name="local",
            runner_type={"name": "local-shell-cmd"},
            parameters={},
        )),
    )
    @mock.patch(
        "st2common.util.action_db.get_runnertype_by_name",
        mock.MagicMock(
            return_value=RunnerTypeDB(name="foo", runner_parameters={})),
    )
    @mock.patch.object(
        Action,
        "get_by_ref",
        mock.MagicMock(
            return_value={"runner_type": {
                "name": "local-shell-cmd"
            }}),
    )
    @mock.patch.object(Policy, "query", mock.MagicMock(return_value=[]))
    @mock.patch.object(Notifier, "_get_trace_context",
                       mock.MagicMock(return_value={}))
    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)

    @mock.patch(
        "st2common.util.action_db.get_action_by_ref",
        mock.MagicMock(return_value=ActionDB(
            pack="core",
            name="local",
            runner_type={"name": "local-shell-cmd"},
            parameters={},
        )),
    )
    @mock.patch(
        "st2common.util.action_db.get_runnertype_by_name",
        mock.MagicMock(
            return_value=RunnerTypeDB(name="foo", runner_parameters={})),
    )
    @mock.patch.object(
        Action,
        "get_by_ref",
        mock.MagicMock(
            return_value={"runner_type": {
                "name": "local-shell-cmd"
            }}),
    )
    @mock.patch.object(Policy, "query", mock.MagicMock(return_value=[]))
    @mock.patch.object(Notifier, "_get_trace_context",
                       mock.MagicMock(return_value={}))
    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)

    @mock.patch(
        "st2common.util.action_db.get_action_by_ref",
        mock.MagicMock(return_value=ActionDB(
            pack="core", name="local", runner_type={"name": "local-shell-cmd"
                                                    })),
    )
    @mock.patch(
        "st2common.util.action_db.get_runnertype_by_name",
        mock.MagicMock(return_value=RunnerTypeDB(
            name="foo", runner_parameters={"runner_foo": "foo"})),
    )
    @mock.patch.object(
        Action,
        "get_by_ref",
        mock.MagicMock(
            return_value={"runner_type": {
                "name": "local-shell-cmd"
            }}),
    )
    @mock.patch.object(Policy, "query", mock.MagicMock(return_value=[]))
    @mock.patch.object(Notifier, "_post_generic_trigger",
                       mock.MagicMock(return_value=True))
    @mock.patch.object(Notifier, "_get_trace_context",
                       mock.MagicMock(return_value={}))
    @mock.patch("st2common.transport.reactor.TriggerDispatcher.dispatch")
    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": "Command mamma mia succeeded.",
            "data": {
                "result": "{}",
                "stdout": "stuff happens"
            },
            "action_ref": "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)

    @mock.patch.object(Notifier, "_get_runner_ref",
                       mock.MagicMock(return_value="local-shell-cmd"))
    @mock.patch.object(Notifier, "_get_trace_context",
                       mock.MagicMock(return_value={}))
    @mock.patch("st2common.transport.reactor.TriggerDispatcher.dispatch")
    def test_post_generic_trigger_emit_when_default_value_is_used(
            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 LIVEACTION_COMPLETED_STATES:
                exp = {
                    "status": status,
                    "start_timestamp": str(liveaction_db.start_timestamp),
                    "result": {},
                    "parameters": {},
                    "action_ref": "core.local",
                    "runner_ref": "local-shell-cmd",
                    "execution_id": str(MOCK_EXECUTION.id),
                    "action_name": "core.local",
                }
                dispatch.assert_called_with("core.st2.generic.actiontrigger",
                                            payload=exp,
                                            trace_context={})

        self.assertEqual(dispatch.call_count, len(LIVEACTION_COMPLETED_STATES))

    @mock.patch(
        "oslo_config.cfg.CONF.action_sensor",
        mock.MagicMock(emit_when=["scheduled", "pending", "abandoned"]),
    )
    @mock.patch.object(Notifier, "_get_runner_ref",
                       mock.MagicMock(return_value="local-shell-cmd"))
    @mock.patch.object(Notifier, "_get_trace_context",
                       mock.MagicMock(return_value={}))
    @mock.patch("st2common.transport.reactor.TriggerDispatcher.dispatch")
    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": "core.local",
                    "runner_ref": "local-shell-cmd",
                    "execution_id": str(MOCK_EXECUTION.id),
                    "action_name": "core.local",
                }
                dispatch.assert_called_with("core.st2.generic.actiontrigger",
                                            payload=exp,
                                            trace_context={})

        self.assertEqual(dispatch.call_count, 3)

    @mock.patch("oslo_config.cfg.CONF.action_sensor.enable",
                mock.MagicMock(return_value=True))
    @mock.patch.object(Notifier, "_get_runner_ref",
                       mock.MagicMock(return_value="local-shell-cmd"))
    @mock.patch.object(Notifier, "_get_trace_context",
                       mock.MagicMock(return_value={}))
    @mock.patch("st2common.transport.reactor.TriggerDispatcher.dispatch")
    @mock.patch("st2actions.notifier.notifier.LiveAction")
    @mock.patch(
        "st2actions.notifier.notifier.policy_service.apply_post_run_policies",
        mock.Mock(),
    )
    def test_process_post_generic_notify_trigger_on_completed_state_default(
            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 LIVEACTION_COMPLETED_STATES:
                exp = {
                    "status": status,
                    "start_timestamp": str(liveaction_db.start_timestamp),
                    "result": {},
                    "parameters": {},
                    "action_ref": "core.local",
                    "runner_ref": "local-shell-cmd",
                    "execution_id": str(MOCK_EXECUTION.id),
                    "action_name": "core.local",
                }
                mock_dispatch.assert_called_with(
                    "core.st2.generic.actiontrigger",
                    payload=exp,
                    trace_context={})

        self.assertEqual(mock_dispatch.call_count,
                         len(LIVEACTION_COMPLETED_STATES))

    @mock.patch(
        "oslo_config.cfg.CONF.action_sensor",
        mock.MagicMock(enable=True,
                       emit_when=["scheduled", "pending", "abandoned"]),
    )
    @mock.patch.object(Notifier, "_get_runner_ref",
                       mock.MagicMock(return_value="local-shell-cmd"))
    @mock.patch.object(Notifier, "_get_trace_context",
                       mock.MagicMock(return_value={}))
    @mock.patch("st2common.transport.reactor.TriggerDispatcher.dispatch")
    @mock.patch("st2actions.notifier.notifier.LiveAction")
    @mock.patch(
        "st2actions.notifier.notifier.policy_service.apply_post_run_policies",
        mock.Mock(),
    )
    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": "core.local",
                    "runner_ref": "local-shell-cmd",
                    "execution_id": str(MOCK_EXECUTION.id),
                    "action_name": "core.local",
                }
                mock_dispatch.assert_called_with(
                    "core.st2.generic.actiontrigger",
                    payload=exp,
                    trace_context={})

        self.assertEqual(mock_dispatch.call_count, 3)