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 _register_rules_from_pack(self, pack, rules): registered_count = 0 for rule in rules: LOG.debug('Loading rule from %s.', rule) try: content = self._meta_loader.load(rule) pack_field = content.get('pack', None) if not pack_field: content['pack'] = pack pack_field = pack if pack_field != pack: raise Exception('Model is in pack "%s" but field "pack" is different: %s' % (pack, pack_field)) rule_api = RuleAPI(**content) rule_api.validate() rule_db = RuleAPI.to_model(rule_api) # Migration from rule without pack to rule with pack. # There might be a rule with same name but in pack `default` # generated in migration script. In this case, we want to # delete so we don't have duplicates. if pack_field != DEFAULT_PACK_NAME: try: rule_ref = ResourceReference.to_string_reference(name=content['name'], pack=DEFAULT_PACK_NAME) LOG.debug('Looking for rule %s in pack %s', content['name'], DEFAULT_PACK_NAME) existing = Rule.get_by_ref(rule_ref) LOG.debug('Existing = %s', existing) if existing: LOG.debug('Found rule in pack default: %s; Deleting.', rule_ref) Rule.delete(existing) except: LOG.exception('Exception deleting rule from %s pack.', DEFAULT_PACK_NAME) try: rule_ref = ResourceReference.to_string_reference(name=content['name'], pack=content['pack']) existing = Rule.get_by_ref(rule_ref) if existing: rule_db.id = existing.id LOG.debug('Found existing rule: %s with id: %s', rule_ref, existing.id) except ValueError: LOG.debug('Rule %s not found. Creating new one.', rule) try: rule_db = Rule.add_or_update(rule_db) extra = {'rule_db': rule_db} LOG.audit('Rule updated. Rule %s from %s.', rule_db, rule, extra=extra) except Exception: LOG.exception('Failed to create rule %s.', rule_api.name) except: LOG.exception('Failed registering rule from %s.', rule) else: registered_count += 1 return registered_count
def __init__(self, connection, queues, trigger_dispatcher=None): super(Notifier, self).__init__(connection, queues) self._trigger_dispatcher = trigger_dispatcher 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 __init__(self, q_connection=None, trigger_dispatcher=None): self._queue_consumer = LiveActionUpdateQueueConsumer(q_connection, self) self._consumer_thread = None self._trigger_dispatcher = trigger_dispatcher 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 _register_trigger_type(self, trigger_definition, attempt_no=0): LOG.debug('Attempt no %s to register trigger %s.', attempt_no, trigger_definition['name']) ref = ResourceReference.to_string_reference(pack=trigger_definition['pack'], name=trigger_definition['name']) if self._is_triggertype_exists(ref): return payload = json.dumps(trigger_definition) try: r = requests.post(url=self._trigger_type_endpoint, data=payload, headers=self._http_post_headers, timeout=self._timeout) if r.status_code == httplib.CREATED: LOG.info('Registered trigger %s.', trigger_definition['name']) elif r.status_code == httplib.CONFLICT: LOG.info('Trigger %s is already registered.', trigger_definition['name']) else: LOG.error('Seeing status code %s on an attempt to register trigger %s.', r.status_code, trigger_definition['name']) except requests.exceptions.ConnectionError: if attempt_no < self._max_attempts: self._retry_wait = self._retry_wait * (attempt_no + 1) LOG.debug(' ConnectionError. Will retry in %ss.', self._retry_wait) eventlet.spawn_after(self._retry_wait, self._register_trigger_type, trigger_definition=trigger_definition, attempt_no=(attempt_no + 1)) else: LOG.warn('Failed to register trigger %s. ' % trigger_definition['name'] + ' Exceeded max attempts to register trigger.') except: LOG.exception('Failed to register trigger %s.', trigger_definition['name'])
def test_exception_thrown_when_rule_creation_no_trigger_yes_triggertype(self): test_fixtures = { 'triggertypes': ['triggertype1.yaml'] } loader = FixturesLoader() fixtures = loader.save_fixtures_to_db(fixtures_pack='generic', fixtures_dict=test_fixtures) triggertypes = fixtures['triggertypes'] trigger_type_ref = ResourceReference.to_string_reference( name=triggertypes['triggertype1.yaml']['name'], pack=triggertypes['triggertype1.yaml']['pack']) rule = { 'name': 'fancyrule', 'trigger': { 'type': trigger_type_ref }, 'criteria': { }, 'action': { 'ref': 'core.local', 'parameters': { 'cmd': 'date' } } } rule_api = RuleAPI(**rule) self.assertRaises(TriggerDoesNotExistException, trigger_service.create_trigger_db_from_rule, rule_api)
def run(self, action_parameters): liveaction_db = action_utils.get_liveaction_by_id(self.liveaction_id) exc = ActionExecution.get(liveaction__id=str(liveaction_db.id)) # Assemble and dispatch trigger trigger_ref = ResourceReference.to_string_reference( pack=INQUIRY_TRIGGER['pack'], name=INQUIRY_TRIGGER['name'] ) trigger_payload = { "id": str(exc.id), "route": self.route } self.trigger_dispatcher.dispatch(trigger_ref, trigger_payload) # We only want to request a pause if this has a parent if liveaction_db.context.get("parent"): # Get the root liveaction and request that it pauses root_liveaction = action_service.get_root_liveaction(liveaction_db) action_service.request_pause( root_liveaction, self.context.get('user', None) ) result = { "schema": self.schema, "roles": self.roles_param, "users": self.users_param, "route": self.route, "ttl": self.ttl } return (LIVEACTION_STATUS_PENDING, result, None)
def to_model(cls, rule): name = getattr(rule, 'name', None) description = getattr(rule, 'description', None) # Create a trigger for the provided rule trigger_db = TriggerService.create_trigger_db_from_rule(rule) trigger = reference.get_str_resource_ref_from_model(trigger_db) criteria = dict(getattr(rule, 'criteria', {})) pack = getattr(rule, 'pack', DEFAULT_PACK_NAME) ref = ResourceReference.to_string_reference(pack=pack, name=name) # Validate criteria validator.validate_criteria(criteria) # Validate trigger parameters validator.validate_trigger_parameters(trigger_db=trigger_db) action = ActionExecutionSpecDB(ref=rule.action['ref'], parameters=rule.action['parameters']) enabled = rule.enabled tags = TagsHelper.to_model(getattr(rule, 'tags', [])) model = cls.model(name=name, description=description, pack=pack, ref=ref, trigger=trigger, criteria=criteria, action=action, enabled=enabled, tags=tags) return model
def to_model(cls, action): name = getattr(action, 'name', None) description = getattr(action, 'description', None) enabled = bool(getattr(action, 'enabled', True)) entry_point = str(action.entry_point) pack = str(action.pack) runner_type = {'name': str(action.runner_type)} parameters = getattr(action, 'parameters', dict()) tags = TagsHelper.to_model(getattr(action, 'tags', [])) ref = ResourceReference.to_string_reference(pack=pack, name=name) if getattr(action, 'notify', None): notify = NotificationsHelper.to_model(action.notify) else: # We use embedded document model for ``notify`` in action model. If notify is # set notify to None, Mongoengine interprets ``None`` as unmodified # field therefore doesn't delete the embedded document. Therefore, we need # to use an empty document. notify = NotificationsHelper.to_model({}) model = cls.model(name=name, description=description, enabled=enabled, entry_point=entry_point, pack=pack, runner_type=runner_type, tags=tags, parameters=parameters, notify=notify, ref=ref) return model
def test_chain_runner_task_is_canceled_while_running(self, request): # Second task in the action is CANCELED, make sure runner doesn't get stuck in an infinite # loop chain_runner = acr.get_runner() chain_runner.entry_point = CHAIN_2_PATH chain_runner.action = ACTION_1 original_run_action = chain_runner._run_action def mock_run_action(*args, **kwargs): original_live_action = args[0] if original_live_action.action == 'wolfpack.a2': status = LIVEACTION_STATUS_CANCELED else: status = LIVEACTION_STATUS_SUCCEEDED request.return_value = (DummyActionExecution(status=status), None) liveaction = original_run_action(*args, **kwargs) return liveaction chain_runner._run_action = mock_run_action 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, _, _ = chain_runner.run({}) self.assertEqual(status, LIVEACTION_STATUS_CANCELED) self.assertNotEqual(chain_runner.chain_holder.actionchain, None) # Chain count should be 2 since the last task doesn't get called since the second one was # canceled self.assertEqual(request.call_count, 2)
def _get_api_models_from_disk(artifact_type, pack_dir=None): loader = ContentPackLoader() artifacts = None if pack_dir: artifacts_dir = loader.get_content_from_pack(pack_dir, artifact_type) pack_name = os.path.basename(os.path.normpath(pack_dir)) artifacts = {pack_name: artifacts_dir} else: packs_dirs = content_utils.get_packs_base_paths() artifacts = loader.get_content(packs_dirs, artifact_type) artifacts_dict = {} for pack_name, pack_path in artifacts.items(): artifacts_paths = registrar.get_resources_from_pack(pack_path) for artifact_path in artifacts_paths: artifact = meta_loader.load(artifact_path) if artifact_type == "sensors": sensors_dir = os.path.dirname(artifact_path) sensor_file_path = os.path.join(sensors_dir, artifact["entry_point"]) artifact["artifact_uri"] = "file://" + sensor_file_path name = artifact.get("name", None) or artifact.get("class_name", None) if not artifact.get("pack", None): artifact["pack"] = pack_name ref = ResourceReference.to_string_reference(name=name, pack=pack_name) API_MODEL = API_MODELS_ARTIFACT_TYPES[artifact_type] # Following conversions are required because we add some fields with # default values in db model. If we don't do these conversions, # we'll see a unnecessary diff for those fields. artifact_api = API_MODEL(**artifact) artifact_db = API_MODEL.to_model(artifact_api) artifact_api = API_MODEL.from_model(artifact_db) artifacts_dict[ref] = artifact_api return artifacts_dict
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) if six.PY2: expected_values = [{u'p1': u'1'}, {u'p1': u'1'}, {u'out': u"{'c2': {'o1': '1'}, 'c1': {'o1': '1'}}"}] else: expected_values = [{'p1': '1'}, {'p1': '1'}, {'out': "{'c1': {'o1': '1'}, 'c2': {'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.')
def to_model(cls, action): name = getattr(action, "name", None) description = getattr(action, "description", None) enabled = bool(getattr(action, "enabled", True)) entry_point = str(action.entry_point) pack = str(action.pack) runner_type = {"name": str(action.runner_type)} parameters = getattr(action, "parameters", dict()) tags = TagsHelper.to_model(getattr(action, "tags", [])) ref = ResourceReference.to_string_reference(pack=pack, name=name) if getattr(action, "notify", None): notify = NotificationsHelper.to_model(action.notify) else: notify = None model = cls.model( name=name, description=description, enable=enabled, enabled=enabled, entry_point=entry_point, pack=pack, runner_type=runner_type, tags=tags, parameters=parameters, notify=notify, ref=ref, ) return model
def register_trigger_type(trigger_definition, attempt_no=0): LOG.debug('Attempt no %s to register trigger %s.', attempt_no, trigger_definition['name']) ref = ResourceReference.to_string_reference(pack=trigger_definition['pack'], name=trigger_definition['name']) if _is_triggertype_exists(ref): return payload = json.dumps(trigger_definition) try: r = requests.post(url=TRIGGER_TYPE_ENDPOINT, data=payload, headers=HTTP_POST_HEADER, timeout=TIMEOUT) if r.status_code == httplib.CREATED: LOG.info('Registered trigger %s.', trigger_definition['name']) elif r.status_code == httplib.CONFLICT: LOG.info('Trigger %s is already registered.', trigger_definition['name']) else: LOG.error('Seeing status code %s on an attempt to register trigger %s.', r.status_code, trigger_definition['name']) except requests.exceptions.ConnectionError: if attempt_no < MAX_ATTEMPTS: retry_wait = RETRY_WAIT * (attempt_no + 1) LOG.debug(' ConnectionError. Will retry in %ss.', retry_wait) eventlet.spawn_after(retry_wait, register_trigger_type, trigger_definition=trigger_definition, attempt_no=(attempt_no + 1)) else: LOG.warn('Failed to register trigger %s. Exceeded max attempts to register trigger.', trigger_definition['name']) except: LOG.exception('Failed to register trigger %s.', trigger_definition['name'])
def test_get_one_by_ref(self): rule_name = RuleViewControllerTestCase.RULE_1.name rule_pack = RuleViewControllerTestCase.RULE_1.pack ref = ResourceReference.to_string_reference(name=rule_name, pack=rule_pack) get_resp = self.__do_get_one(ref) self.assertEqual(get_resp.json['name'], rule_name) self.assertEqual(get_resp.status_int, http_client.OK)
def _register_action(self, pack, action): content = self._meta_loader.load(action) pack_field = content.get('pack', None) if not pack_field: content['pack'] = pack pack_field = pack if pack_field != pack: raise Exception('Model is in pack "%s" but field "pack" is different: %s' % (pack, pack_field)) action_api = ActionAPI(**content) action_api.validate() action_validator.validate_action(action_api) model = ActionAPI.to_model(action_api) action_ref = ResourceReference.to_string_reference(pack=pack, name=str(content['name'])) existing = action_utils.get_action_by_ref(action_ref) if not existing: LOG.debug('Action %s not found. Creating new one with: %s', action_ref, content) else: LOG.debug('Action %s found. Will be updated from: %s to: %s', action_ref, existing, model) model.id = existing.id try: model = Action.add_or_update(model) extra = {'action_db': model} LOG.audit('Action updated. Action %s from %s.', model, action, extra=extra) except Exception: LOG.exception('Failed to write action to db %s.', model.name) raise
def to_model(cls, rule): kwargs = {} kwargs['name'] = getattr(rule, 'name', None) kwargs['description'] = getattr(rule, 'description', None) # Create a trigger for the provided rule trigger_db = TriggerService.create_trigger_db_from_rule(rule) kwargs['trigger'] = reference.get_str_resource_ref_from_model(trigger_db) # Validate trigger parameters validator.validate_trigger_parameters(trigger_db=trigger_db) kwargs['pack'] = getattr(rule, 'pack', DEFAULT_PACK_NAME) kwargs['ref'] = ResourceReference.to_string_reference(pack=kwargs['pack'], name=kwargs['name']) # Validate criteria kwargs['criteria'] = dict(getattr(rule, 'criteria', {})) validator.validate_criteria(kwargs['criteria']) kwargs['action'] = ActionExecutionSpecDB(ref=rule.action['ref'], parameters=rule.action.get('parameters', {})) rule_type = dict(getattr(rule, 'type', {})) if rule_type: kwargs['type'] = RuleTypeSpecDB(ref=rule_type['ref'], parameters=rule_type.get('parameters', {})) kwargs['enabled'] = getattr(rule, 'enabled', False) kwargs['tags'] = TagsHelper.to_model(getattr(rule, 'tags', [])) model = cls.model(**kwargs) return model
def post_trigger(action_execution): if not ACTION_SENSOR_ENABLED: return try: payload = json.dumps({ 'trigger': ResourceReference.to_string_reference( pack=ACTION_TRIGGER_TYPE['pack'], name=ACTION_TRIGGER_TYPE['name']), 'payload': { 'execution_id': str(action_execution.id), 'status': action_execution.status, 'start_timestamp': str(action_execution.start_timestamp), 'action_name': action_execution.action, 'parameters': action_execution.parameters, 'result': action_execution.result } }) LOG.debug('POSTing %s for %s. Payload - %s.', ACTION_TRIGGER_TYPE['name'], action_execution.id, payload) r = requests.post(TRIGGER_INSTANCE_ENDPOINT, data=payload, headers=HTTP_POST_HEADER, timeout=TIMEOUT) except: LOG.exception('Failed to fire trigger for action_execution %s.', str(action_execution.id)) else: if r.status_code in [200, 201, 202]: LOG.debug('POSTed actionexecution %s as a trigger.', action_execution.id) else: LOG.warn('Seeing status code %s on an attempt to post triggerinstance for %s.', r.status_code, action_execution.id)
def _register_internal_trigger_type(trigger_definition): try: trigger_type_db = create_trigger_type_db(trigger_type=trigger_definition) except (NotUniqueError, StackStormDBObjectConflictError): # We ignore conflict error since this operation is idempotent and race is not an issue LOG.debug('Internal trigger type "%s" already exists, ignoring...' % (trigger_definition['name']), exc_info=True) ref = ResourceReference.to_string_reference(name=trigger_definition['name'], pack=trigger_definition['pack']) trigger_type_db = get_trigger_type_db(ref) if trigger_type_db: LOG.debug('Registered internal trigger: %s.', trigger_definition['name']) # trigger types with parameters do no require a shadow trigger. if trigger_type_db and not trigger_type_db.parameters_schema: try: trigger_db = create_shadow_trigger(trigger_type_db) extra = {'trigger_db': trigger_db} LOG.audit('Trigger created for parameter-less internal TriggerType. Trigger.id=%s' % (trigger_db.id), extra=extra) except StackStormDBObjectConflictError: LOG.debug('Shadow trigger "%s" already exists. Ignoring.', trigger_type_db.get_reference().ref, exc_info=True) except (ValidationError, ValueError): LOG.exception('Validation failed in shadow trigger. TriggerType=%s.', trigger_type_db.get_reference().ref) raise return trigger_type_db
def test_create_or_update_trigger_db_simple_triggers(self): test_fixtures = { 'triggertypes': ['triggertype1.yaml'] } loader = FixturesLoader() fixtures = loader.save_fixtures_to_db(fixtures_pack='generic', fixtures_dict=test_fixtures) triggertypes = fixtures['triggertypes'] trigger_type_ref = ResourceReference.to_string_reference( name=triggertypes['triggertype1.yaml']['name'], pack=triggertypes['triggertype1.yaml']['pack']) trigger = { 'name': triggertypes['triggertype1.yaml']['name'], 'pack': triggertypes['triggertype1.yaml']['pack'], 'type': trigger_type_ref } trigger_service.create_or_update_trigger_db(trigger) triggers = Trigger.get_all() self.assertTrue(len(triggers) == 1, 'Only one trigger should be created.') self.assertTrue(triggers[0]['name'] == triggertypes['triggertype1.yaml']['name']) # Try adding duplicate trigger_service.create_or_update_trigger_db(trigger) triggers = Trigger.get_all() self.assertTrue(len(triggers) == 1, 'Only one trigger should be present.') self.assertTrue(triggers[0]['name'] == triggertypes['triggertype1.yaml']['name'])
def test_chain_runner_chain_second_task_times_out(self, request): # Second task in the chain times out so the action chain status should be timeout chain_runner = acr.get_runner() chain_runner.entry_point = CHAIN_2_PATH chain_runner.action = ACTION_1 original_run_action = chain_runner._run_action def mock_run_action(*args, **kwargs): original_live_action = args[0] liveaction = original_run_action(*args, **kwargs) if original_live_action.action == 'wolfpack.a2': # Mock a timeout for second task liveaction.status = LIVEACTION_STATUS_TIMED_OUT return liveaction chain_runner._run_action = mock_run_action 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, _, _ = chain_runner.run({}) self.assertEqual(status, LIVEACTION_STATUS_TIMED_OUT) 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)
def test_get_all(self): holder = TimersHolder() for _, model in TestTimersHolder.MODELS.items(): holder.add_trigger( ref=ResourceReference.to_string_reference(pack=model["pack"], name=model["name"]), trigger=model ) self.assertEqual(len(holder.get_all()), 5)
def to_model(cls, alias): name = alias.name description = getattr(alias, "description", None) pack = alias.pack ref = ResourceReference.to_string_reference(pack=pack, name=name) enabled = getattr(alias, "enabled", True) action_ref = alias.action_ref formats = alias.formats ack = getattr(alias, "ack", None) result = getattr(alias, "result", None) extra = getattr(alias, "extra", None) model = cls.model( name=name, description=description, pack=pack, ref=ref, enabled=enabled, action_ref=action_ref, formats=formats, ack=ack, result=result, extra=extra, ) return model
def test_add_trigger(self): holder = TimersHolder() for _, model in TestTimersHolder.MODELS.items(): holder.add_trigger( ref=ResourceReference.to_string_reference(pack=model['pack'], name=model['name']), trigger=model ) self.assertEqual(len(holder._timers), 5)
def to_model(cls, alias): model = super(cls, cls).to_model(alias) model.name = alias.name model.pack = alias.pack model.ref = ResourceReference.to_string_reference(pack=model.pack, name=model.name) model.action_ref = alias.action_ref model.formats = alias.formats return model
def test_chain_runner_missing_param_temp(self, request): 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() chain_runner.run({}) self.assertEqual(request.call_count, 0, 'No call expected.')
def test_get_all_filters_filter_by_type(self): holder = TimersHolder() for _, model in TestTimersHolder.MODELS.items(): holder.add_trigger( ref=ResourceReference.to_string_reference(pack=model["pack"], name=model["name"]), trigger=model ) self.assertEqual(len(holder.get_all(timer_type=INTERVAL_TIMER_TRIGGER_REF)), 3) self.assertEqual(len(holder.get_all(timer_type=DATE_TIMER_TRIGGER_REF)), 1) self.assertEqual(len(holder.get_all(timer_type=CRON_TIMER_TRIGGER_REF)), 1)
def test_remove_trigger(self): holder = TimersHolder() model = TestTimersHolder.MODELS.get("cron1.yaml", None) self.assertTrue(model is not None) ref = ResourceReference.to_string_reference(pack=model["pack"], name=model["name"]) holder.add_trigger(ref, model) self.assertEqual(len(holder._timers), 1) holder.remove_trigger(ref, model) self.assertEqual(len(holder._timers), 0)
def create_trigger_db(trigger_api): # TODO: This is used only in trigger API controller. We should get rid of this. trigger_ref = ResourceReference.to_string_reference(name=trigger_api.name, pack=trigger_api.pack) trigger_db = get_trigger_db_by_ref(trigger_ref) if not trigger_db: trigger_db = TriggerAPI.to_model(trigger_api) LOG.debug("Verified trigger and formulated TriggerDB=%s", trigger_db) trigger_db = Trigger.add_or_update(trigger_db) return trigger_db
def test_get_one_by_ref(self): post_resp = self.__do_post(TestRuleController.RULE_1) rule_name = post_resp.json['name'] rule_pack = post_resp.json['pack'] ref = ResourceReference.to_string_reference(name=rule_name, pack=rule_pack) rule_id = post_resp.json['id'] get_resp = self.__do_get_one(ref) self.assertEqual(get_resp.json['name'], rule_name) self.assertEqual(get_resp.status_int, http_client.OK) self.__do_delete(rule_id)
def test_chain_runner_vars_action_params(self, request): chain_runner = acr.get_runner() chain_runner.entry_point = CHAIN_WITH_ACTIONPARAM_VARS 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({'input_a': 'two'}) self.assertNotEqual(chain_runner.chain_holder.actionchain, None) expected_value = {'inttype': 1, 'strtype': 'two', 'booltype': True} mock_args, _ = request.call_args self.assertEqual(mock_args[0].parameters, expected_value)
def test_chain_runner_list_param_temp(self, request): chain_runner = acr.get_runner() chain_runner.entry_point = CHAIN_LIST_TEMP_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({"s1": 1, "s2": 2, "s3": 3, "s4": 4}) self.assertNotEqual(chain_runner.chain_holder.actionchain, None) mock_args, _ = request.call_args self.assertEqual(mock_args[0].parameters, {"p1": "[2, 3, 4]"})
def to_model(cls, action): model = super(cls, cls).to_model(action) model.enabled = bool(action.enabled) model.entry_point = str(action.entry_point) model.pack = str(action.pack) model.runner_type = {'name': str(action.runner_type)} model.parameters = getattr(action, 'parameters', dict()) model.tags = TagsHelper.to_model(getattr(action, 'tags', [])) model.ref = ResourceReference.to_string_reference(pack=model.pack, name=model.name) if getattr(action, 'notify', None): model.notify = NotificationsHelper.to_model(action.notify) return model
def test_get_one_by_ref(self): post_resp = self.__do_post(RulesControllerTestCase.RULE_1) rule_name = post_resp.json['name'] rule_pack = post_resp.json['pack'] ref = ResourceReference.to_string_reference(name=rule_name, pack=rule_pack) rule_id = post_resp.json['id'] get_resp = self.__do_get_one(ref) self.assertEqual(get_resp.json['name'], rule_name) self.assertEqual(get_resp.status_int, http_client.OK) self.__do_delete(rule_id) post_resp = self.__do_post(RulesControllerTestCase.RULE_SPACE) rule_name = post_resp.json['name'] rule_pack = post_resp.json['pack'] ref = ResourceReference.to_string_reference(name=rule_name, pack=rule_pack) rule_id = post_resp.json['id'] get_resp = self.__do_get_one(ref) self.assertEqual(get_resp.json['name'], rule_name) self.assertEqual(get_resp.status_int, http_client.OK) self.__do_delete(rule_id)
def test_chain_runner_success_path_with_wait(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) # based on the chain the callcount is known to be 3. Not great but works. self.assertEqual(request.call_count, 3)
def test_chain_runner_dict_param_temp(self, request): chain_runner = acr.get_runner() chain_runner.entry_point = CHAIN_DICT_TEMP_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({'s1': 1, 's2': 2, 's3': 3, 's4': 4}) self.assertNotEqual(chain_runner.chain_holder.actionchain, None) expected_value = {"p1": {"p1.3": "[3, 4]", "p1.2": "2", "p1.1": "1"}} mock_args, _ = request.call_args self.assertEqual(mock_args[0].parameters, expected_value)
def test_chain_runner_failure_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() status, _, _ = chain_runner.run({}) self.assertEqual(status, LIVEACTION_STATUS_FAILED) self.assertNotEqual(chain_runner.chain_holder.actionchain, None) # based on the chain the callcount is known to be 2. Not great but works. self.assertEqual(request.call_count, 2)
def to_model(cls, alias): name = alias.name description = getattr(alias, 'description', None) pack = alias.pack ref = ResourceReference.to_string_reference(pack=pack, name=name) enabled = getattr(alias, 'enabled', True) action_ref = alias.action_ref formats = alias.formats ack = getattr(alias, 'ack', None) result = getattr(alias, 'result', None) model = cls.model(name=name, description=description, pack=pack, ref=ref, enabled=enabled, action_ref=action_ref, formats=formats, ack=ack, result=result) return model
def test_params_and_parameters_attributes_both_work(self, _): action_ref = ResourceReference.to_string_reference( name=ACTION_2.name, pack=ACTION_2.pack ) # "params" attribute used chain_runner = acr.get_runner() chain_runner.entry_point = CHAIN_ACTION_PARAMS_ATTRIBUTE chain_runner.action = ACTION_2 chain_runner.liveaction = LiveActionDB(action=action_ref) chain_runner.pre_run() original_build_liveaction_object = chain_runner._build_liveaction_object def mock_build_liveaction_object(action_node, resolved_params, parent_context): # Verify parameters are correctly passed to the action self.assertEqual(resolved_params, {"pparams": "v1"}) original_build_liveaction_object( action_node=action_node, resolved_params=resolved_params, parent_context=parent_context, ) chain_runner._build_liveaction_object = mock_build_liveaction_object action_parameters = {} status, output, _ = chain_runner.run(action_parameters=action_parameters) self.assertEqual(status, LIVEACTION_STATUS_SUCCEEDED) # "parameters" attribute used chain_runner = acr.get_runner() chain_runner.entry_point = CHAIN_ACTION_PARAMETERS_ATTRIBUTE chain_runner.action = ACTION_2 chain_runner.liveaction = LiveActionDB(action=action_ref) chain_runner.pre_run() def mock_build_liveaction_object(action_node, resolved_params, parent_context): # Verify parameters are correctly passed to the action self.assertEqual(resolved_params, {"pparameters": "v1"}) original_build_liveaction_object( action_node=action_node, resolved_params=resolved_params, parent_context=parent_context, ) chain_runner._build_liveaction_object = mock_build_liveaction_object action_parameters = {} status, output, _ = chain_runner.run(action_parameters=action_parameters) self.assertEqual(status, LIVEACTION_STATUS_SUCCEEDED)
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)
def test_get_all_filters_filter_by_type(self): holder = TimersHolder() for _, model in TestTimersHolder.MODELS.items(): holder.add_trigger( ref=ResourceReference.to_string_reference(pack=model["pack"], name=model["name"]), trigger=model, ) self.assertEqual( len(holder.get_all(timer_type=INTERVAL_TIMER_TRIGGER_REF)), 3) self.assertEqual( len(holder.get_all(timer_type=DATE_TIMER_TRIGGER_REF)), 1) self.assertEqual( len(holder.get_all(timer_type=CRON_TIMER_TRIGGER_REF)), 1)
def _get_trigger_db(trigger): # TODO: This method should die in a fire # XXX: Do not make this method public. if isinstance(trigger, dict): name = trigger.get('name', None) pack = trigger.get('pack', None) if name and pack: ref = ResourceReference.to_string_reference(name=name, pack=pack) return get_trigger_db_by_ref(ref) return get_trigger_db_given_type_and_params(type=trigger['type'], parameters=trigger.get('parameters', {})) else: raise Exception('Unrecognized object')
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)
def _create_save_rule(trigger, action=None, enabled=True): name = 'rule-1' pack = 'default' ref = ResourceReference.to_string_reference(name=name, pack=pack) created = RuleDB(name=name, pack=pack, ref=ref) created.description = '' created.enabled = enabled created.trigger = reference.get_str_resource_ref_from_model(trigger) created.criteria = {} created.action = ActionExecutionSpecDB() action_ref = ResourceReference(pack=action.pack, name=action.name).ref created.action.ref = action_ref created.action.pack = action.pack created.action.parameters = {} return Rule.add_or_update(created)
def _get_api_models_from_db(persistence_model, pack_dir=None): filters = {} if pack_dir: pack_name = os.path.basename(os.path.normpath(pack_dir)) filters = {'pack': pack_name} models = persistence_model.query(**filters) models_dict = {} for model in models: model_pack = getattr(model, 'pack', None) or DEFAULT_PACK_NAME model_ref = ResourceReference.to_string_reference(name=model.name, pack=model_pack) if getattr(model, 'id', None): del model.id API_MODEL = API_MODELS_PERSISTENT_MODELS[persistence_model] models_dict[model_ref] = API_MODEL.from_model(model) return models_dict
def validate_action(action_api): runner_db = _get_runner_model(action_api) # Check if pack is valid. if not _is_valid_pack(action_api.pack): packs_base_paths = get_packs_base_paths() packs_base_paths = ','.join(packs_base_paths) msg = ('Content pack "%s" is not found or doesn\'t contain actions directory. ' 'Searched in: %s' % (action_api.pack, packs_base_paths)) raise ValueValidationException(msg) # Check if parameters defined are valid. action_ref = ResourceReference.to_string_reference(pack=action_api.pack, name=action_api.name) _validate_parameters(action_ref, action_api.parameters, runner_db.runner_parameters)
def test_to_string_reference(self): ref = ResourceReference.to_string_reference(pack='mapack', name='moname') self.assertEqual(ref, 'mapack.moname') expected_msg = r'Pack name should not contain "\."' self.assertRaisesRegexp(ValueError, expected_msg, ResourceReference.to_string_reference, pack='pack.invalid', name='bar') expected_msg = 'Both pack and name needed for building' self.assertRaisesRegexp(ValueError, expected_msg, ResourceReference.to_string_reference, pack='pack', name=None) expected_msg = 'Both pack and name needed for building' self.assertRaisesRegexp(ValueError, expected_msg, ResourceReference.to_string_reference, pack=None, name='name')
def create_or_update_trigger_type_db(trigger_type): """ Create or update a trigger type db object in the db given trigger_type definition as dict. :param trigger_type: Trigger type model. :type trigger_type: ``dict`` :rtype: ``object`` """ assert isinstance(trigger_type, dict) trigger_type_api = TriggerTypeAPI(**trigger_type) trigger_type_api.validate() trigger_type_api = TriggerTypeAPI.to_model(trigger_type_api) ref = ResourceReference.to_string_reference(name=trigger_type_api.name, pack=trigger_type_api.pack) existing_trigger_type_db = get_trigger_type_db(ref) if existing_trigger_type_db: is_update = True else: is_update = False if is_update: trigger_type_api.id = existing_trigger_type_db.id try: trigger_type_db = TriggerType.add_or_update(trigger_type_api) except StackStormDBObjectConflictError: # Operation is idempotent and trigger could have already been created by # another process. Ignore object already exists because it simply means # there was a race and object is already in the database. trigger_type_db = get_trigger_type_db(ref) is_update = True extra = {'trigger_type_db': trigger_type_db} if is_update: LOG.audit('TriggerType updated. TriggerType.id=%s' % (trigger_type_db.id), extra=extra) else: LOG.audit('TriggerType created. TriggerType.id=%s' % (trigger_type_db.id), extra=extra) return trigger_type_db
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.')
def _register_internal_trigger_type(trigger_definition): try: trigger_type_db = create_trigger_type_db( trigger_type=trigger_definition, log_not_unique_error_as_debug=True) except (NotUniqueError, StackStormDBObjectConflictError): # We ignore conflict error since this operation is idempotent and race is not an issue LOG.debug( 'Internal trigger type "%s" already exists, ignoring error...' % (trigger_definition["name"])) ref = ResourceReference.to_string_reference( name=trigger_definition["name"], pack=trigger_definition["pack"]) trigger_type_db = get_trigger_type_db(ref) if trigger_type_db: LOG.debug("Registered internal trigger: %s.", trigger_definition["name"]) # trigger types with parameters do no require a shadow trigger. if trigger_type_db and not trigger_type_db.parameters_schema: try: trigger_db = create_shadow_trigger( trigger_type_db, log_not_unique_error_as_debug=True) extra = {"trigger_db": trigger_db} LOG.audit( "Trigger created for parameter-less internal TriggerType. Trigger.id=%s" % (trigger_db.id), extra=extra, ) except (NotUniqueError, StackStormDBObjectConflictError): LOG.debug( 'Shadow trigger "%s" already exists. Ignoring.', trigger_type_db.get_reference().ref, exc_info=True, ) except (ValidationError, ValueError): LOG.exception( "Validation failed in shadow trigger. TriggerType=%s.", trigger_type_db.get_reference().ref, ) raise return trigger_type_db
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.")
def to_model(cls, rule): kwargs = {} kwargs["name"] = getattr(rule, "name", None) kwargs["description"] = getattr(rule, "description", None) # Validate trigger parameters # Note: This must happen before we create a trigger, otherwise create trigger could fail # with a cryptic error trigger = getattr(rule, "trigger", {}) trigger_type_ref = trigger.get("type", None) parameters = trigger.get("parameters", {}) validator.validate_trigger_parameters( trigger_type_ref=trigger_type_ref, parameters=parameters ) # Create a trigger for the provided rule trigger_db = TriggerService.create_trigger_db_from_rule(rule) kwargs["trigger"] = reference.get_str_resource_ref_from_model(trigger_db) kwargs["pack"] = getattr(rule, "pack", DEFAULT_PACK_NAME) kwargs["ref"] = ResourceReference.to_string_reference( pack=kwargs["pack"], name=kwargs["name"] ) # Validate criteria kwargs["criteria"] = dict(getattr(rule, "criteria", {})) validator.validate_criteria(kwargs["criteria"]) kwargs["action"] = ActionExecutionSpecDB( ref=rule.action["ref"], parameters=rule.action.get("parameters", {}) ) rule_type = dict(getattr(rule, "type", {})) if rule_type: kwargs["type"] = RuleTypeSpecDB( ref=rule_type["ref"], parameters=rule_type.get("parameters", {}) ) kwargs["enabled"] = getattr(rule, "enabled", False) kwargs["context"] = getattr(rule, "context", dict()) kwargs["tags"] = TagsHelper.to_model(getattr(rule, "tags", [])) kwargs["metadata_file"] = getattr(rule, "metadata_file", None) model = cls.model(**kwargs) return model
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.')
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'])
def to_model(cls, rule): kwargs = {} kwargs['name'] = getattr(rule, 'name', None) kwargs['description'] = getattr(rule, 'description', None) # Validate trigger parameters # Note: This must happen before we create a trigger, otherwise create trigger could fail # with a cryptic error trigger = getattr(rule, 'trigger', {}) trigger_type_ref = trigger.get('type', None) parameters = trigger.get('parameters', {}) validator.validate_trigger_parameters( trigger_type_ref=trigger_type_ref, parameters=parameters) # Create a trigger for the provided rule trigger_db = TriggerService.create_trigger_db_from_rule(rule) kwargs['trigger'] = reference.get_str_resource_ref_from_model( trigger_db) kwargs['pack'] = getattr(rule, 'pack', DEFAULT_PACK_NAME) kwargs['ref'] = ResourceReference.to_string_reference( pack=kwargs['pack'], name=kwargs['name']) # Validate criteria kwargs['criteria'] = dict(getattr(rule, 'criteria', {})) validator.validate_criteria(kwargs['criteria']) kwargs['action'] = ActionExecutionSpecDB(ref=rule.action['ref'], parameters=rule.action.get( 'parameters', {})) rule_type = dict(getattr(rule, 'type', {})) if rule_type: kwargs['type'] = RuleTypeSpecDB(ref=rule_type['ref'], parameters=rule_type.get( 'parameters', {})) kwargs['enabled'] = getattr(rule, 'enabled', False) kwargs['context'] = getattr(rule, 'context', dict()) kwargs['tags'] = TagsHelper.to_model(getattr(rule, 'tags', [])) kwargs['metadata_file'] = getattr(rule, 'metadata_file', None) model = cls.model(**kwargs) return model
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.')
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)
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'])
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)
def create_trigger_type_db(trigger_type): """ Creates a trigger type db object in the db given trigger_type definition as dict. :param trigger_type: Trigger type model. :type trigger_type: ``dict`` :rtype: ``object`` """ trigger_type_api = TriggerTypeAPI(**trigger_type) ref = ResourceReference.to_string_reference(name=trigger_type_api.name, pack=trigger_type_api.pack) trigger_type_db = get_trigger_type_db(ref) if not trigger_type_db: trigger_type_db = TriggerTypeAPI.to_model(trigger_type_api) LOG.debug('verified trigger and formulated TriggerDB=%s', trigger_type_db) trigger_type_db = TriggerType.add_or_update(trigger_type_db) return trigger_type_db