Exemple #1
0
    def test_add_or_update_given_trace_context(self):
        trace_context = {'id_': str(self.trace_empty.id)}
        action_execution_id = 'action_execution_1'
        rule_id = 'rule_1'
        trigger_instance_id = 'trigger_instance_1'
        trace_service.add_or_update_given_trace_context(
            trace_context,
            action_executions=[action_execution_id],
            rules=[rule_id],
            trigger_instances=[trigger_instance_id])

        retrieved_trace_db = Trace.get_by_id(self.trace_empty.id)
        self.assertEqual(len(retrieved_trace_db.action_executions), 1,
                         'Expected updated action_executions.')
        self.assertEqual(retrieved_trace_db.action_executions[0].object_id,
                         action_execution_id,
                         'Expected updated action_executions.')

        self.assertEqual(len(retrieved_trace_db.rules), 1,
                         'Expected updated rules.')
        self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id,
                         'Expected updated rules.')

        self.assertEqual(len(retrieved_trace_db.trigger_instances), 1,
                         'Expected updated trigger_instances.')
        self.assertEqual(retrieved_trace_db.trigger_instances[0].object_id,
                         trigger_instance_id,
                         'Expected updated trigger_instances.')

        Trace.delete(retrieved_trace_db)
        Trace.add_or_update(self.trace_empty)
Exemple #2
0
    def test_add_or_update_given_trace_context(self):
        trace_context = {'id_': str(self.trace_empty.id)}
        action_execution_id = 'action_execution_1'
        rule_id = 'rule_1'
        trigger_instance_id = 'trigger_instance_1'
        trace_service.add_or_update_given_trace_context(
            trace_context,
            action_executions=[action_execution_id],
            rules=[rule_id],
            trigger_instances=[trigger_instance_id])

        retrieved_trace_db = Trace.get_by_id(self.trace_empty.id)
        self.assertEqual(len(retrieved_trace_db.action_executions), 1,
                         'Expected updated action_executions.')
        self.assertEqual(retrieved_trace_db.action_executions[0].object_id, action_execution_id,
                         'Expected updated action_executions.')

        self.assertEqual(len(retrieved_trace_db.rules), 1, 'Expected updated rules.')
        self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id, 'Expected updated rules.')

        self.assertEqual(len(retrieved_trace_db.trigger_instances), 1,
                         'Expected updated trigger_instances.')
        self.assertEqual(retrieved_trace_db.trigger_instances[0].object_id, trigger_instance_id,
                         'Expected updated trigger_instances.')

        Trace.delete(retrieved_trace_db)
        Trace.add_or_update(self.trace_empty)
Exemple #3
0
    def process(self, pre_ack_response):
        trigger_instance, message = self._decompose_pre_ack_process_response(
            pre_ack_response)
        if not trigger_instance:
            raise ValueError("No trigger_instance provided for processing.")

        get_driver().inc_counter("trigger.%s.processed" %
                                 (trigger_instance.trigger))

        try:
            # Use trace_context from the message and if not found create a new context
            # and use the trigger_instance.id as trace_tag.
            trace_context = message.get(TRACE_CONTEXT, None)
            if not trace_context:
                trace_context = {
                    TRACE_ID: "trigger_instance-%s" % str(trigger_instance.id)
                }
            # add a trace or update an existing trace with trigger_instance
            trace_service.add_or_update_given_trace_context(
                trace_context=trace_context,
                trigger_instances=[
                    trace_service.get_trace_component_for_trigger_instance(
                        trigger_instance)
                ],
            )

            container_utils.update_trigger_instance_status(
                trigger_instance,
                trigger_constants.TRIGGER_INSTANCE_PROCESSING)

            with CounterWithTimer(key="rule.processed"):
                with Timer(key="trigger.%s.processed" %
                           (trigger_instance.trigger)):
                    self.rules_engine.handle_trigger_instance(trigger_instance)

            container_utils.update_trigger_instance_status(
                trigger_instance, trigger_constants.TRIGGER_INSTANCE_PROCESSED)
        except:
            # TODO : Capture the reason for failure.
            container_utils.update_trigger_instance_status(
                trigger_instance,
                trigger_constants.TRIGGER_INSTANCE_PROCESSING_FAILED)
            # This could be a large message but at least in case of an exception
            # we get to see more context.
            # Beyond this point code cannot really handle the exception anyway so
            # eating up the exception.
            LOG.exception("Failed to handle trigger_instance %s.",
                          trigger_instance)
            return
Exemple #4
0
    def test_triggered_execution(self):
        docs = {
            'trigger_type': copy.deepcopy(fixture.ARTIFACTS['trigger_type']),
            'trigger': copy.deepcopy(fixture.ARTIFACTS['trigger']),
            'rule': copy.deepcopy(fixture.ARTIFACTS['rule']),
            'trigger_instance': copy.deepcopy(fixture.ARTIFACTS['trigger_instance'])}

        # Trigger an action execution.
        trigger_type = TriggerType.add_or_update(
            TriggerTypeAPI.to_model(TriggerTypeAPI(**docs['trigger_type'])))
        trigger = Trigger.add_or_update(TriggerAPI.to_model(TriggerAPI(**docs['trigger'])))
        rule = RuleAPI.to_model(RuleAPI(**docs['rule']))
        rule.trigger = reference.get_str_resource_ref_from_model(trigger)
        rule = Rule.add_or_update(rule)
        trigger_instance = TriggerInstance.add_or_update(
            TriggerInstanceAPI.to_model(TriggerInstanceAPI(**docs['trigger_instance'])))
        trace_service.add_or_update_given_trace_context(
            trace_context={'trace_tag': 'test_triggered_execution_trace'},
            trigger_instances=[str(trigger_instance.id)])
        enforcer = RuleEnforcer(trigger_instance, rule)
        enforcer.enforce()

        # Wait for the action execution to complete and then confirm outcome.
        liveaction = LiveAction.get(context__trigger_instance__id=str(trigger_instance.id))
        self.assertIsNotNone(liveaction)
        liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_FAILED)

        execution = self._get_action_execution(
            liveaction__id=str(liveaction.id),
            raise_exception=True
        )

        self.assertDictEqual(execution.trigger, vars(TriggerAPI.from_model(trigger)))
        self.assertDictEqual(execution.trigger_type, vars(TriggerTypeAPI.from_model(trigger_type)))
        self.assertDictEqual(execution.trigger_instance,
                             vars(TriggerInstanceAPI.from_model(trigger_instance)))
        self.assertDictEqual(execution.rule, vars(RuleAPI.from_model(rule)))
        action = action_utils.get_action_by_ref(liveaction.action)
        self.assertDictEqual(execution.action, vars(ActionAPI.from_model(action)))
        runner = RunnerType.get_by_name(action.runner_type['name'])
        self.assertDictEqual(execution.runner, vars(RunnerTypeAPI.from_model(runner)))
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(execution.start_timestamp, liveaction.start_timestamp)
        self.assertEqual(execution.end_timestamp, liveaction.end_timestamp)
        self.assertEqual(execution.result, liveaction.result)
        self.assertEqual(execution.status, liveaction.status)
        self.assertEqual(execution.context, liveaction.context)
        self.assertEqual(execution.liveaction['callback'], liveaction.callback)
        self.assertEqual(execution.liveaction['action'], liveaction.action)
Exemple #5
0
    def test_add_or_update_given_trace_context_new(self):
        trace_context = {'trace_tag': 'awesome_test_trace'}
        action_execution_id = 'action_execution_1'
        rule_id = 'rule_1'
        trigger_instance_id = 'trigger_instance_1'

        pre_add_or_update_traces = len(Trace.get_all())
        trace_db = trace_service.add_or_update_given_trace_context(
            trace_context,
            action_executions=[action_execution_id],
            rules=[rule_id],
            trigger_instances=[trigger_instance_id])
        post_add_or_update_traces = len(Trace.get_all())

        self.assertTrue(post_add_or_update_traces > pre_add_or_update_traces,
                        'Expected new Trace to be created.')

        retrieved_trace_db = Trace.get_by_id(trace_db.id)
        self.assertEqual(len(retrieved_trace_db.action_executions), 1,
                         'Expected updated action_executions.')
        self.assertEqual(retrieved_trace_db.action_executions[0].object_id, action_execution_id,
                         'Expected updated action_executions.')

        self.assertEqual(len(retrieved_trace_db.rules), 1, 'Expected updated rules.')
        self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id, 'Expected updated rules.')

        self.assertEqual(len(retrieved_trace_db.trigger_instances), 1,
                         'Expected updated trigger_instances.')
        self.assertEqual(retrieved_trace_db.trigger_instances[0].object_id, trigger_instance_id,
                         'Expected updated trigger_instances.')

        Trace.delete(retrieved_trace_db)
Exemple #6
0
    def test_add_or_update_given_trace_context_new_with_causals(self):
        trace_context = {'trace_tag': 'causal_test_trace'}
        action_execution_id = 'action_execution_1'
        rule_id = 'rule_1'
        trigger_instance_id = 'trigger_instance_1'

        pre_add_or_update_traces = len(Trace.get_all())
        trace_db = trace_service.add_or_update_given_trace_context(
            trace_context,
            action_executions=[{
                'id': action_execution_id,
                'caused_by': {
                    'id': '%s:%s' % (rule_id, trigger_instance_id),
                    'type': 'rule'
                }
            }],
            rules=[{
                'id': rule_id,
                'caused_by': {
                    'id': trigger_instance_id,
                    'type': 'trigger-instance'
                }
            }],
            trigger_instances=[trigger_instance_id])
        post_add_or_update_traces = len(Trace.get_all())

        self.assertTrue(post_add_or_update_traces > pre_add_or_update_traces,
                        'Expected new Trace to be created.')

        retrieved_trace_db = Trace.get_by_id(trace_db.id)
        self.assertEqual(len(retrieved_trace_db.action_executions), 1,
                         'Expected updated action_executions.')
        self.assertEqual(retrieved_trace_db.action_executions[0].object_id,
                         action_execution_id,
                         'Expected updated action_executions.')
        self.assertEqual(retrieved_trace_db.action_executions[0].caused_by, {
            'id': '%s:%s' % (rule_id, trigger_instance_id),
            'type': 'rule'
        }, 'Expected updated action_executions.')

        self.assertEqual(len(retrieved_trace_db.rules), 1,
                         'Expected updated rules.')
        self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id,
                         'Expected updated rules.')
        self.assertEqual(retrieved_trace_db.rules[0].caused_by, {
            'id': trigger_instance_id,
            'type': 'trigger-instance'
        }, 'Expected updated rules.')

        self.assertEqual(len(retrieved_trace_db.trigger_instances), 1,
                         'Expected updated trigger_instances.')
        self.assertEqual(retrieved_trace_db.trigger_instances[0].object_id,
                         trigger_instance_id,
                         'Expected updated trigger_instances.')
        self.assertEqual(retrieved_trace_db.trigger_instances[0].caused_by, {},
                         'Expected updated rules.')

        Trace.delete(retrieved_trace_db)
Exemple #7
0
    def process(self, instance):
        trigger = instance['trigger']
        payload = instance['payload']

        trigger_instance = None
        try:
            trigger_instance = container_utils.create_trigger_instance(
                trigger,
                payload or {},
                date_utils.get_datetime_utc_now(),
                raise_on_no_trigger=True)
        except:
            # We got a trigger ref but we were unable to create a trigger instance.
            # This could be because a trigger object wasn't found in db for the ref.
            LOG.exception('Failed to create trigger_instance %s.', instance)
            return

        if trigger_instance:
            try:
                # Use trace_context from the instance and if not found create a new context
                # and use the trigger_instance.id as trace_tag.
                trace_context = instance.get(TRACE_CONTEXT, None)
                if not trace_context:
                    trace_context = {
                        TRACE_ID:
                        'trigger_instance-%s' % str(trigger_instance.id)
                    }
                # add a trace or update an existing trace with trigger_instance
                trace_service.add_or_update_given_trace_context(
                    trace_context=trace_context,
                    trigger_instances=[
                        trace_service.get_trace_component_for_trigger_instance(
                            trigger_instance)
                    ])
                self.rules_engine.handle_trigger_instance(trigger_instance)
            except:
                # This could be a large message but at least in case of an exception
                # we get to see more context.
                # Beyond this point code cannot really handle the exception anyway so
                # eating up the exception.
                LOG.exception('Failed to handle trigger_instance %s.',
                              instance)
                return
Exemple #8
0
    def process(self, pre_ack_response):
        trigger_instance, message = self._decompose_pre_ack_process_response(pre_ack_response)
        if not trigger_instance:
            raise ValueError('No trigger_instance provided for processing.')

        get_driver().inc_counter('trigger.%s.processed' % (trigger_instance.trigger))

        try:
            # Use trace_context from the message and if not found create a new context
            # and use the trigger_instance.id as trace_tag.
            trace_context = message.get(TRACE_CONTEXT, None)
            if not trace_context:
                trace_context = {
                    TRACE_ID: 'trigger_instance-%s' % str(trigger_instance.id)
                }
            # add a trace or update an existing trace with trigger_instance
            trace_service.add_or_update_given_trace_context(
                trace_context=trace_context,
                trigger_instances=[
                    trace_service.get_trace_component_for_trigger_instance(trigger_instance)
                ]
            )

            container_utils.update_trigger_instance_status(
                trigger_instance, trigger_constants.TRIGGER_INSTANCE_PROCESSING)

            with CounterWithTimer(key='rule.processed'):
                with Timer(key='trigger.%s.processed' % (trigger_instance.trigger)):
                    self.rules_engine.handle_trigger_instance(trigger_instance)

            container_utils.update_trigger_instance_status(
                trigger_instance, trigger_constants.TRIGGER_INSTANCE_PROCESSED)
        except:
            # TODO : Capture the reason for failure.
            container_utils.update_trigger_instance_status(
                trigger_instance, trigger_constants.TRIGGER_INSTANCE_PROCESSING_FAILED)
            # This could be a large message but at least in case of an exception
            # we get to see more context.
            # Beyond this point code cannot really handle the exception anyway so
            # eating up the exception.
            LOG.exception('Failed to handle trigger_instance %s.', trigger_instance)
            return
Exemple #9
0
    def process(self, instance):
        trigger = instance['trigger']
        payload = instance['payload']

        trigger_instance = None
        try:
            trigger_instance = container_utils.create_trigger_instance(
                trigger,
                payload or {},
                date_utils.get_datetime_utc_now(),
                raise_on_no_trigger=True)
        except:
            # We got a trigger ref but we were unable to create a trigger instance.
            # This could be because a trigger object wasn't found in db for the ref.
            LOG.exception('Failed to create trigger_instance %s.', instance)
            return

        if trigger_instance:
            try:
                # Use trace_context from the instance and if not found create a new context
                # and use the trigger_instance.id as trace_tag.
                trace_context = instance.get(TRACE_CONTEXT, None)
                if not trace_context:
                    trace_context = {
                        TRACE_ID: 'trigger_instance-%s' % str(trigger_instance.id)
                    }
                # add a trace or update an existing trace with trigger_instance
                trace_service.add_or_update_given_trace_context(
                    trace_context=trace_context,
                    trigger_instances=[
                        trace_service.get_trace_component_for_trigger_instance(trigger_instance)
                    ])
                self.rules_engine.handle_trigger_instance(trigger_instance)
            except:
                # This could be a large message but at least in case of an exception
                # we get to see more context.
                # Beyond this point code cannot really handle the exception anyway so
                # eating up the exception.
                LOG.exception('Failed to handle trigger_instance %s.', instance)
                return
Exemple #10
0
    def test_add_or_update_given_trace_context_new(self):
        trace_context = {"trace_tag": "awesome_test_trace"}
        action_execution_id = "action_execution_1"
        rule_id = "rule_1"
        trigger_instance_id = "trigger_instance_1"

        pre_add_or_update_traces = len(Trace.get_all())
        trace_db = trace_service.add_or_update_given_trace_context(
            trace_context,
            action_executions=[action_execution_id],
            rules=[rule_id],
            trigger_instances=[trigger_instance_id],
        )
        post_add_or_update_traces = len(Trace.get_all())

        self.assertTrue(
            post_add_or_update_traces > pre_add_or_update_traces,
            "Expected new Trace to be created.",
        )

        retrieved_trace_db = Trace.get_by_id(trace_db.id)
        self.assertEqual(
            len(retrieved_trace_db.action_executions),
            1,
            "Expected updated action_executions.",
        )
        self.assertEqual(
            retrieved_trace_db.action_executions[0].object_id,
            action_execution_id,
            "Expected updated action_executions.",
        )

        self.assertEqual(len(retrieved_trace_db.rules), 1,
                         "Expected updated rules.")
        self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id,
                         "Expected updated rules.")

        self.assertEqual(
            len(retrieved_trace_db.trigger_instances),
            1,
            "Expected updated trigger_instances.",
        )
        self.assertEqual(
            retrieved_trace_db.trigger_instances[0].object_id,
            trigger_instance_id,
            "Expected updated trigger_instances.",
        )

        Trace.delete(retrieved_trace_db)
Exemple #11
0
    def test_add_or_update_given_trace_context_new_with_causals(self):
        trace_context = {'trace_tag': 'causal_test_trace'}
        action_execution_id = 'action_execution_1'
        rule_id = 'rule_1'
        trigger_instance_id = 'trigger_instance_1'

        pre_add_or_update_traces = len(Trace.get_all())
        trace_db = trace_service.add_or_update_given_trace_context(
            trace_context,
            action_executions=[{'id': action_execution_id,
                                'caused_by': {'id': '%s:%s' % (rule_id, trigger_instance_id),
                                              'type': 'rule'}}],
            rules=[{'id': rule_id,
                    'caused_by': {'id': trigger_instance_id, 'type': 'trigger-instance'}}],
            trigger_instances=[trigger_instance_id])
        post_add_or_update_traces = len(Trace.get_all())

        self.assertTrue(post_add_or_update_traces > pre_add_or_update_traces,
                        'Expected new Trace to be created.')

        retrieved_trace_db = Trace.get_by_id(trace_db.id)
        self.assertEqual(len(retrieved_trace_db.action_executions), 1,
                         'Expected updated action_executions.')
        self.assertEqual(retrieved_trace_db.action_executions[0].object_id, action_execution_id,
                         'Expected updated action_executions.')
        self.assertEqual(retrieved_trace_db.action_executions[0].caused_by,
                         {'id': '%s:%s' % (rule_id, trigger_instance_id),
                          'type': 'rule'},
                         'Expected updated action_executions.')

        self.assertEqual(len(retrieved_trace_db.rules), 1, 'Expected updated rules.')
        self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id, 'Expected updated rules.')
        self.assertEqual(retrieved_trace_db.rules[0].caused_by,
                         {'id': trigger_instance_id, 'type': 'trigger-instance'},
                         'Expected updated rules.')

        self.assertEqual(len(retrieved_trace_db.trigger_instances), 1,
                         'Expected updated trigger_instances.')
        self.assertEqual(retrieved_trace_db.trigger_instances[0].object_id, trigger_instance_id,
                         'Expected updated trigger_instances.')
        self.assertEqual(retrieved_trace_db.trigger_instances[0].caused_by, {},
                         'Expected updated rules.')

        Trace.delete(retrieved_trace_db)
Exemple #12
0
    def test_add_or_update_given_trace_context_new(self):
        trace_context = {'trace_tag': 'awesome_test_trace'}
        action_execution_id = 'action_execution_1'
        rule_id = 'rule_1'
        trigger_instance_id = 'trigger_instance_1'

        pre_add_or_update_traces = len(Trace.get_all())
        trace_db = trace_service.add_or_update_given_trace_context(
            trace_context,
            action_executions=[action_execution_id],
            rules=[rule_id],
            trigger_instances=[trigger_instance_id])
        post_add_or_update_traces = len(Trace.get_all())

        self.assertTrue(post_add_or_update_traces > pre_add_or_update_traces,
                        'Expected new Trace to be created.')

        retrieved_trace_db = Trace.get_by_id(trace_db.id)
        self.assertEqual(len(retrieved_trace_db.action_executions), 1,
                         'Expected updated action_executions.')
        self.assertEqual(retrieved_trace_db.action_executions[0].object_id,
                         action_execution_id,
                         'Expected updated action_executions.')

        self.assertEqual(len(retrieved_trace_db.rules), 1,
                         'Expected updated rules.')
        self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id,
                         'Expected updated rules.')

        self.assertEqual(len(retrieved_trace_db.trigger_instances), 1,
                         'Expected updated trigger_instances.')
        self.assertEqual(retrieved_trace_db.trigger_instances[0].object_id,
                         trigger_instance_id,
                         'Expected updated trigger_instances.')

        Trace.delete(retrieved_trace_db)
Exemple #13
0
    def test_triggered_execution(self):
        docs = {
            "trigger_type":
            copy.deepcopy(fixture.ARTIFACTS["trigger_type"]),
            "trigger":
            copy.deepcopy(fixture.ARTIFACTS["trigger"]),
            "rule":
            copy.deepcopy(fixture.ARTIFACTS["rule"]),
            "trigger_instance":
            copy.deepcopy(fixture.ARTIFACTS["trigger_instance"]),
        }

        # Trigger an action execution.
        trigger_type = TriggerType.add_or_update(
            TriggerTypeAPI.to_model(TriggerTypeAPI(**docs["trigger_type"])))
        trigger = Trigger.add_or_update(
            TriggerAPI.to_model(TriggerAPI(**docs["trigger"])))
        rule = RuleAPI.to_model(RuleAPI(**docs["rule"]))
        rule.trigger = reference.get_str_resource_ref_from_model(trigger)
        rule = Rule.add_or_update(rule)
        trigger_instance = TriggerInstance.add_or_update(
            TriggerInstanceAPI.to_model(
                TriggerInstanceAPI(**docs["trigger_instance"])))
        trace_service.add_or_update_given_trace_context(
            trace_context={"trace_tag": "test_triggered_execution_trace"},
            trigger_instances=[str(trigger_instance.id)],
        )
        enforcer = RuleEnforcer(trigger_instance, rule)
        enforcer.enforce()

        # Wait for the action execution to complete and then confirm outcome.
        liveaction = LiveAction.get(
            context__trigger_instance__id=str(trigger_instance.id))
        self.assertIsNotNone(liveaction)
        liveaction = self._wait_on_status(
            liveaction, action_constants.LIVEACTION_STATUS_FAILED)

        execution = self._get_action_execution(liveaction__id=str(
            liveaction.id),
                                               raise_exception=True)

        self.assertDictEqual(execution.trigger,
                             vars(TriggerAPI.from_model(trigger)))
        self.assertDictEqual(execution.trigger_type,
                             vars(TriggerTypeAPI.from_model(trigger_type)))
        self.assertDictEqual(
            execution.trigger_instance,
            vars(TriggerInstanceAPI.from_model(trigger_instance)),
        )
        self.assertDictEqual(execution.rule, vars(RuleAPI.from_model(rule)))
        action = action_utils.get_action_by_ref(liveaction.action)
        self.assertDictEqual(execution.action,
                             vars(ActionAPI.from_model(action)))
        runner = RunnerType.get_by_name(action.runner_type["name"])
        self.assertDictEqual(execution.runner,
                             vars(RunnerTypeAPI.from_model(runner)))
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(execution.start_timestamp, liveaction.start_timestamp)
        # NOTE: Timestamp of liveaction and execution may be a bit different, depending on how long
        # it takes to persist each object in the database
        self.assertEqual(
            execution.end_timestamp.replace(microsecond=0),
            liveaction.end_timestamp.replace(microsecond=0),
        )
        self.assertEqual(execution.result, liveaction.result)
        self.assertEqual(execution.status, liveaction.status)
        self.assertEqual(execution.context, liveaction.context)
        self.assertEqual(execution.liveaction["callback"], liveaction.callback)
        self.assertEqual(execution.liveaction["action"], liveaction.action)
Exemple #14
0
    def test_add_or_update_given_trace_context_new_with_causals(self):
        trace_context = {"trace_tag": "causal_test_trace"}
        action_execution_id = "action_execution_1"
        rule_id = "rule_1"
        trigger_instance_id = "trigger_instance_1"

        pre_add_or_update_traces = len(Trace.get_all())
        trace_db = trace_service.add_or_update_given_trace_context(
            trace_context,
            action_executions=[{
                "id": action_execution_id,
                "caused_by": {
                    "id": "%s:%s" % (rule_id, trigger_instance_id),
                    "type": "rule",
                },
            }],
            rules=[{
                "id": rule_id,
                "caused_by": {
                    "id": trigger_instance_id,
                    "type": "trigger-instance",
                },
            }],
            trigger_instances=[trigger_instance_id],
        )
        post_add_or_update_traces = len(Trace.get_all())

        self.assertTrue(
            post_add_or_update_traces > pre_add_or_update_traces,
            "Expected new Trace to be created.",
        )

        retrieved_trace_db = Trace.get_by_id(trace_db.id)
        self.assertEqual(
            len(retrieved_trace_db.action_executions),
            1,
            "Expected updated action_executions.",
        )
        self.assertEqual(
            retrieved_trace_db.action_executions[0].object_id,
            action_execution_id,
            "Expected updated action_executions.",
        )
        self.assertEqual(
            retrieved_trace_db.action_executions[0].caused_by,
            {
                "id": "%s:%s" % (rule_id, trigger_instance_id),
                "type": "rule"
            },
            "Expected updated action_executions.",
        )

        self.assertEqual(len(retrieved_trace_db.rules), 1,
                         "Expected updated rules.")
        self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id,
                         "Expected updated rules.")
        self.assertEqual(
            retrieved_trace_db.rules[0].caused_by,
            {
                "id": trigger_instance_id,
                "type": "trigger-instance"
            },
            "Expected updated rules.",
        )

        self.assertEqual(
            len(retrieved_trace_db.trigger_instances),
            1,
            "Expected updated trigger_instances.",
        )
        self.assertEqual(
            retrieved_trace_db.trigger_instances[0].object_id,
            trigger_instance_id,
            "Expected updated trigger_instances.",
        )
        self.assertEqual(
            retrieved_trace_db.trigger_instances[0].caused_by,
            {},
            "Expected updated rules.",
        )

        Trace.delete(retrieved_trace_db)