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.')
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.")
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)
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 _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)
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)
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)
# 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:
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)
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",
# 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))
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)