def test(self): # Full integration test to ensure that when a subscription receives an update # the `QuerySubscriptionConsumer` successfully retries the subscription and # calls the correct callback, which should result in an incident being created. callback = subscriber_registry[INCIDENTS_SNUBA_SUBSCRIPTION_TYPE] def exception_callback(*args, **kwargs): # We want to just error after the callback so that we can see the result of # processing. This means the offset won't be committed, but that's fine, we # can still check the results. callback(*args, **kwargs) raise KeyboardInterrupt() value_name = query_aggregation_to_snuba[QueryAggregations( self.subscription.aggregation)][2] subscriber_registry[ INCIDENTS_SNUBA_SUBSCRIPTION_TYPE] = exception_callback message = { "version": 1, "payload": { "subscription_id": self.subscription.subscription_id, "values": { "data": [{ value_name: self.trigger.alert_threshold + 1 }] }, "timestamp": "2020-01-01T01:23:45.1234", }, } self.producer.produce(self.topic, json.dumps(message)) self.producer.flush() def active_incident(): return Incident.objects.filter( type=IncidentType.ALERT_TRIGGERED.value, alert_rule=self.rule).exclude( status=IncidentStatus.CLOSED.value) consumer = QuerySubscriptionConsumer("hi", topic=self.topic) with self.assertChanges(lambda: active_incident().exists(), before=False, after=True), self.tasks(): consumer.run() assert len(mail.outbox) == 1 handler = EmailActionHandler(self.action, active_incident().get(), self.project) message = handler.build_message( handler.generate_email_context(TriggerStatus.ACTIVE), TriggerStatus.ACTIVE, self.user.id) out = mail.outbox[0] assert out.to == [self.user.email] assert out.subject == message.subject built_message = message.build(self.user.email) assert out.body == built_message.body
def test(self): # Full integration test to ensure that when a subscription receives an update # the `QuerySubscriptionConsumer` successfully retries the subscription and # calls the correct callback, which should result in an incident being created. message = { "version": 1, "payload": { "subscription_id": self.subscription.subscription_id, "values": {"data": [{"some_col": self.trigger.alert_threshold + 1}]}, "timestamp": "2020-01-01T01:23:45.1234", }, } self.producer.produce(self.topic, json.dumps(message)) self.producer.flush() def active_incident(): return Incident.objects.filter( type=IncidentType.ALERT_TRIGGERED.value, alert_rule=self.rule ).exclude(status=IncidentStatus.CLOSED.value) consumer = QuerySubscriptionConsumer("hi", topic=self.topic) original_callback = subscriber_registry[INCIDENTS_SNUBA_SUBSCRIPTION_TYPE] def shutdown_callback(*args, **kwargs): # We want to just exit after the callback so that we can see the result of # processing. original_callback(*args, **kwargs) consumer.shutdown() subscriber_registry[INCIDENTS_SNUBA_SUBSCRIPTION_TYPE] = shutdown_callback with self.feature(["organizations:incidents", "organizations:performance-view"]): with self.assertChanges( lambda: active_incident().exists(), before=False, after=True ), self.tasks(), self.capture_on_commit_callbacks(execute=True): consumer.run() assert len(mail.outbox) == 1 handler = EmailActionHandler(self.action, active_incident().get(), self.project) message = handler.build_message( generate_incident_trigger_email_context( handler.project, handler.incident, handler.action.alert_rule_trigger, TriggerStatus.ACTIVE, ), TriggerStatus.ACTIVE, self.user.id, ) out = mail.outbox[0] assert out.to == [self.user.email] assert out.subject == message.subject built_message = message.build(self.user.email) assert out.body == built_message.body
def test_user_alerts_disabled(self): UserOption.objects.set_value( user=self.user, key="mail:alert", value=0, project=self.project ) action = self.create_alert_rule_trigger_action( target_type=AlertRuleTriggerAction.TargetType.USER, target_identifier=six.text_type(self.user.id), ) handler = EmailActionHandler(action, self.incident, self.project) assert handler.get_targets() == [(self.user.id, self.user.email)]
def test_user(self): action = self.create_alert_rule_trigger_action( target_identifier=six.text_type(self.user.id)) incident = self.create_incident() handler = EmailActionHandler(action, incident, self.project) with self.tasks(): handler.resolve() out = mail.outbox[0] assert out.to == [self.user.email] assert out.subject.startswith("Incident Alert Rule Resolved")
def test_team(self): new_user = self.create_user() self.create_team_membership(team=self.team, user=new_user) action = self.create_alert_rule_trigger_action( target_type=AlertRuleTriggerAction.TargetType.TEAM, target_identifier=six.text_type(self.team.id), ) handler = EmailActionHandler(action, self.incident, self.project) assert set(handler.get_targets()) == set( [(self.user.id, self.user.email), (new_user.id, new_user.email)] )
def test_user(self): action = self.create_alert_rule_trigger_action( target_identifier=six.text_type(self.user.id) ) incident = self.create_incident(status=IncidentStatus.CRITICAL.value) handler = EmailActionHandler(action, incident, self.project) with self.tasks(): handler.fire() out = mail.outbox[0] assert out.to == [self.user.email] assert out.subject == u"[Critical] {} - {}".format(incident.title, self.project.slug)
def test_environment(self): status = TriggerStatus.ACTIVE environments = [ self.create_environment(project=self.project, name="prod"), self.create_environment(project=self.project, name="dev"), ] alert_rule = self.create_alert_rule(environment=environments) alert_rule_trigger = self.create_alert_rule_trigger(alert_rule=alert_rule) action = self.create_alert_rule_trigger_action(alert_rule_trigger=alert_rule_trigger) incident = self.create_incident() handler = EmailActionHandler(action, incident, self.project) assert "dev, prod" == handler.generate_email_context(status).get("environment")
def test(self): status = TriggerStatus.ACTIVE action = self.create_alert_rule_trigger_action() incident = self.create_incident() handler = EmailActionHandler(action, incident, self.project) expected = { "link": absolute_uri( reverse( "sentry-metric-alert", kwargs={ "organization_slug": incident.organization.slug, "incident_id": incident.identifier, }, )), "rule_link": absolute_uri( reverse( "sentry-alert-rule", kwargs={ "organization_slug": incident.organization.slug, "project_slug": self.project.slug, "alert_rule_id": action.alert_rule_trigger.alert_rule_id, }, )), "incident_name": incident.title, "aggregate": handler.query_aggregations_display[QueryAggregations( action.alert_rule_trigger.alert_rule.aggregation)], "query": action.alert_rule_trigger.alert_rule.query, "threshold": action.alert_rule_trigger.alert_threshold, "status": INCIDENT_STATUS[IncidentStatus(incident.status)], "environment": "All", "is_critical": False, "is_warning": False, "threshold_direction_string": ">", "time_window": "10 minutes", "triggered_at": timezone.now(), "unsubscribe_link": None, } assert expected == handler.generate_email_context(status)
def test_user(self): incident = self.create_incident() action = self.create_alert_rule_trigger_action( target_identifier=six.text_type(self.user.id), triggered_for_incident=incident, ) handler = EmailActionHandler(action, incident, self.project) with self.tasks(): incident.status = IncidentStatus.CLOSED.value handler.resolve(1000) out = mail.outbox[0] assert out.to == [self.user.email] assert out.subject == u"[Resolved] {} - {}".format(incident.title, self.project.slug)
def run_test(self, incident, method): action = self.create_alert_rule_trigger_action( target_identifier=str(self.user.id), triggered_for_incident=incident, ) handler = EmailActionHandler(action, incident, self.project) with self.tasks(): handler.fire(1000) out = mail.outbox[0] assert out.to == [self.user.email] assert out.subject == "[{}] {} - {}".format( INCIDENT_STATUS[IncidentStatus(incident.status)], incident.title, self.project.slug)
def test_team_alert_disabled(self): UserOption.objects.set_value( user=self.user, key="mail:alert", value=0, project=self.project ) new_user = self.create_user() self.create_team_membership(team=self.team, user=new_user) action = self.create_alert_rule_trigger_action( target_type=AlertRuleTriggerAction.TargetType.TEAM, target_identifier=six.text_type(self.team.id), ) handler = EmailActionHandler(action, self.incident, self.project) assert set(handler.get_targets()) == set([(new_user.id, new_user.email)])
def test_user_alerts_disabled(self): NotificationSetting.objects.update_settings( ExternalProviders.EMAIL, NotificationSettingTypes.ISSUE_ALERTS, NotificationSettingOptionValues.NEVER, user=self.user, project=self.project, ) action = self.create_alert_rule_trigger_action( target_type=AlertRuleTriggerAction.TargetType.USER, target_identifier=str(self.user.id), ) handler = EmailActionHandler(action, self.incident, self.project) assert handler.get_targets() == [(self.user.id, self.user.email)]
def test_user_email_routing(self): new_email = "*****@*****.**" UserOption.objects.create(user=self.user, project=self.project, key="mail:email", value=new_email) action = self.create_alert_rule_trigger_action( target_type=AlertRuleTriggerAction.TargetType.USER, target_identifier=str(self.user.id), ) handler = EmailActionHandler(action, self.incident, self.project) assert handler.get_targets() == [(self.user.id, new_email)]
def test(self): status = TriggerStatus.ACTIVE action = self.create_alert_rule_trigger_action() incident = self.create_incident() handler = EmailActionHandler(action, incident, self.project) expected = { "link": absolute_uri( reverse( "sentry-metric-alert", kwargs={ "organization_slug": incident.organization.slug, "incident_id": incident.identifier, }, )), "rule_link": absolute_uri( reverse( "sentry-alert-rule", kwargs={ "organization_slug": incident.organization.slug, "project_slug": self.project.slug, "alert_rule_id": action.alert_rule_trigger.alert_rule_id, }, )), "incident_name": incident.title, "aggregate": handler.query_aggregations_display[QueryAggregations( action.alert_rule_trigger.alert_rule.aggregation)], "query": action.alert_rule_trigger.alert_rule.query, "threshold": action.alert_rule_trigger.alert_threshold, "status": handler.status_display[status], } assert expected == handler.generate_email_context(status)
def test_team_email_routing(self): new_user = self.create_user() new_email = "*****@*****.**" UserOption.objects.create(user=self.user, project=self.project, key="mail:email", value=new_email) UserOption.objects.create(user=new_user, project=self.project, key="mail:email", value=new_email) self.create_team_membership(team=self.team, user=new_user) action = self.create_alert_rule_trigger_action( target_type=AlertRuleTriggerAction.TargetType.TEAM, target_identifier=str(self.team.id), ) handler = EmailActionHandler(action, self.incident, self.project) assert set(handler.get_targets()) == { (self.user.id, new_email), (new_user.id, new_email), }
def test_team_alert_disabled(self): NotificationSetting.objects.update_settings( ExternalProviders.EMAIL, NotificationSettingTypes.ISSUE_ALERTS, NotificationSettingOptionValues.NEVER, user=self.user, project=self.project, ) disabled_user = self.create_user() NotificationSetting.objects.update_settings( ExternalProviders.EMAIL, NotificationSettingTypes.ISSUE_ALERTS, NotificationSettingOptionValues.NEVER, user=disabled_user, ) new_user = self.create_user() self.create_team_membership(team=self.team, user=new_user) action = self.create_alert_rule_trigger_action( target_type=AlertRuleTriggerAction.TargetType.TEAM, target_identifier=str(self.team.id), ) handler = EmailActionHandler(action, self.incident, self.project) assert set(handler.get_targets()) == {(new_user.id, new_user.email)}