def test_invalidates_snooze(self, mock_processor): group = self.create_group( project=self.project, status=GroupStatus.IGNORED) event = self.create_event(group=group) snooze = GroupSnooze.objects.create( group=group, until=timezone.now() - timedelta(hours=1), ) post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, is_new_group_environment=True, ) mock_processor.assert_called_with(event, True, False, True, True) assert not GroupSnooze.objects.filter( id=snooze.id, ).exists() group = Group.objects.get(id=group.id) assert group.status == GroupStatus.UNRESOLVED
def test_record_affected_code(self, mock_record_affected_code): group = self.create_group(project=self.project) event = self.create_event(group=group) with self.settings(SENTRY_ENABLE_EXPLORE_CODE=False): post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, ) assert not mock_record_affected_code.delay.called with self.settings(SENTRY_ENABLE_EXPLORE_CODE=True): post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, ) mock_record_affected_code.delay.assert_called_once_with( event=event, )
def test_service_hook_fires_on_alert(self, mock_processor, mock_process_service_hook): group = self.create_group(project=self.project) event = self.create_event(group=group) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [ (mock_callback, mock_futures), ] hook = ServiceHook.objects.create( project_id=self.project.id, actor_id=self.user.id, events=['event.alert'], ) with self.feature('projects:servicehooks'): post_process_group( event=event, is_new=False, is_regression=False, is_sample=False, is_new_group_environment=False, ) mock_process_service_hook.delay.assert_called_once_with( servicehook_id=hook.id, event=event, )
def test_owner_assignment_existing_assignment(self): self.make_ownership() event = self.store_event( data={ 'message': 'oh no', 'platform': 'python', 'stacktrace': { 'frames': [ {'filename': 'src/app/example.py'} ] } }, project_id=self.project.id ) event.group.assignee_set.create( team=self.team, project=self.project) post_process_group( event=event, is_new=False, is_regression=False, is_sample=False, is_new_group_environment=False, ) assignee = event.group.assignee_set.first() assert assignee.user is None assert assignee.team == self.team
def test_group_refresh(self, mock_processor): group1 = self.create_group(project=self.project) group2 = self.create_group(project=self.project) event = self.create_event(group=group1) assert event.group_id == group1.id assert event.group == group1 with self.tasks(): merge_group(group1.id, group2.id) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [ (mock_callback, mock_futures), ] post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, is_new_group_environment=True, ) assert event.group == group2 assert event.group_id == group2.id
def test_record_affected_user(self, mock_record_affected_user): group = self.create_group(project=self.project) event = self.create_event(group=group) post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, ) mock_record_affected_user.delay.assert_called_once_with( event=event, )
def test_processes_resource_change_task_on_new_group(self, delay): group = self.create_group(project=self.project) event = self.create_event(group=group) post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, is_new_group_environment=False, ) delay.assert_called_once_with( action='created', sender='Group', instance_id=group.id, )
def test_maintains_valid_snooze(self): group = self.create_group(project=self.project) event = self.create_event(group=group) snooze = GroupSnooze.objects.create( group=group, until=timezone.now() + timedelta(hours=1), ) post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, ) assert GroupSnooze.objects.filter( id=snooze.id, ).exists()
def test_execute_rule(self, mock_get_rules, mock_execute_rule): action_id = "sentry.rules.actions.notify_event.NotifyEventAction" condition_id = "sentry.rules.conditions.first_seen_event.FirstSeenEventCondition" group = self.create_group(project=self.project) event = self.create_event(group=group) mock_get_rules.return_value = [ Rule(id=1, data={"actions": [{"id": action_id}], "conditions": [{"id": condition_id}]}) ] post_process_group(group=group, event=event, is_new=False, is_regression=False, is_sample=False) assert not mock_execute_rule.delay.called post_process_group(group=group, event=event, is_new=True, is_regression=False, is_sample=False) mock_execute_rule.delay.assert_called_once_with( rule_id=1, event=event, is_new=True, is_regression=False, is_sample=False )
def test_service_hook_does_not_fire_without_event(self, mock_process_service_hook): group = self.create_group(project=self.project) event = self.create_event(group=group) ServiceHook.objects.create( project_id=self.project.id, actor_id=self.user.id, events=[], ) with self.feature('projects:servicehooks'): post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, is_new_group_environment=False, ) assert not mock_process_service_hook.delay.mock_calls
def test_owner_assignment_ownership_does_not_exist(self): event = self.store_event( data={ 'message': 'oh no', 'platform': 'python', 'stacktrace': { 'frames': [ {'filename': 'src/app/example.py'} ] } }, project_id=self.project.id ) post_process_group( event=event, is_new=False, is_regression=False, is_sample=False, is_new_group_environment=False, ) assert not event.group.assignee_set.exists()
def test_rule_processor(self, mock_processor): group = self.create_group(project=self.project) event = self.create_event(group=group) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [ (mock_callback, mock_futures), ] post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, ) mock_processor.assert_called_once_with(event, True, False, False) mock_processor.return_value.apply.assert_called_once_with() mock_callback.assert_called_once_with(event, mock_futures)
def test_group_created_sends_webhook(self, safe_urlopen): issue = self.create_group(project=self.project) event = self.create_event(group=issue) with self.tasks(): post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, is_new_group_environment=False, ) data = json.loads(faux(safe_urlopen).kwargs['data']) assert data['action'] == 'created' assert data['installation']['uuid'] == self.install.uuid assert data['data']['issue']['id'] == six.text_type(issue.id) assert faux(safe_urlopen).kwargs_contain('headers.Content-Type') assert faux(safe_urlopen).kwargs_contain('headers.Request-ID') assert faux(safe_urlopen).kwargs_contain('headers.Sentry-Hook-Resource') assert faux(safe_urlopen).kwargs_contain('headers.Sentry-Hook-Timestamp') assert faux(safe_urlopen).kwargs_contain('headers.Sentry-Hook-Signature')
def test_service_hook_fires_on_new_event(self, mock_process_service_hook): group = self.create_group(project=self.project) event = self.create_event(group=group) hook = ServiceHook.objects.create( project_id=self.project.id, actor_id=self.user.id, events=['event.created'], ) with self.feature('projects:servicehooks'): post_process_group( event=event, is_new=False, is_regression=False, is_sample=False, is_new_group_environment=False, ) mock_process_service_hook.delay.assert_called_once_with( servicehook_id=hook.id, event=event, )
def test_group_created_sends_webhook(self, safe_urlopen): event = self.store_event(data={}, project_id=self.project.id) with self.tasks(): post_process_group( is_new=True, is_regression=False, is_new_group_environment=False, cache_key=write_event_to_cache(event), group_id=event.group_id, ) data = json.loads(faux(safe_urlopen).kwargs["data"]) assert data["action"] == "created" assert data["installation"]["uuid"] == self.install.uuid assert data["data"]["issue"]["id"] == six.text_type(event.group.id) assert faux(safe_urlopen).kwargs_contain("headers.Content-Type") assert faux(safe_urlopen).kwargs_contain("headers.Request-ID") assert faux(safe_urlopen).kwargs_contain( "headers.Sentry-Hook-Resource") assert faux(safe_urlopen).kwargs_contain( "headers.Sentry-Hook-Timestamp") assert faux(safe_urlopen).kwargs_contain( "headers.Sentry-Hook-Signature")
def test_service_hook_does_not_fire_without_alert( self, mock_processor, mock_process_service_hook): event = self.store_event(data={}, project_id=self.project.id) cache_key = write_event_to_cache(event) mock_processor.return_value.apply.return_value = [] self.create_service_hook( project=self.project, organization=self.project.organization, actor=self.user, events=["event.alert"], ) with self.feature("projects:servicehooks"): post_process_group( is_new=False, is_regression=False, is_new_group_environment=False, cache_key=cache_key, group_id=event.group_id, ) assert not mock_process_service_hook.delay.mock_calls
def test_service_hook_does_not_fire_without_alert( self, mock_processor, mock_process_service_hook): group = self.create_group(project=self.project) event = self.create_event(group=group) mock_processor.return_value.apply.return_value = [] self.create_service_hook( project=self.project, organization=self.project.organization, actor=self.user, events=['event.alert'], ) with self.feature('projects:servicehooks'): post_process_group( event=event, is_new=False, is_regression=False, is_sample=False, is_new_group_environment=False, ) assert not mock_process_service_hook.delay.mock_calls
def test_rule_processor_backwards_compat(self, mock_processor): event = self.store_event(data={}, project_id=self.project.id) cache_key = write_event_to_cache(event) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [(mock_callback, mock_futures)] post_process_group( is_new=True, is_regression=False, is_new_group_environment=True, group_id=event.group_id, cache_key=cache_key, ) mock_processor.assert_called_once_with(EventMatcher(event), True, False, True, False) mock_processor.return_value.apply.assert_called_once_with() mock_callback.assert_called_once_with(EventMatcher(event), mock_futures)
def test_owner_assignment_owner_is_gone(self): self.make_ownership() # Remove the team so the rule match will fail to resolve self.team.delete() event = self.store_event(data={ 'message': 'oh no', 'platform': 'python', 'stacktrace': { 'frames': [{ 'filename': 'src/app/example.py' }] } }, project_id=self.project.id) post_process_group( event=event, is_new=False, is_regression=False, is_sample=False, is_new_group_environment=False, ) assignee = event.group.assignee_set.first() assert assignee is None
def test_owner_assignment_assign_user(self): self.make_ownership() event = self.store_event( data={ 'message': 'oh no', 'platform': 'python', 'stacktrace': { 'frames': [ {'filename': 'src/app.py'} ] } }, project_id=self.project.id ) post_process_group( event=event, is_new=False, is_regression=False, is_sample=False, is_new_group_environment=False, ) assignee = event.group.assignee_set.first() assert assignee.user == self.user assert assignee.team is None
def test_service_hook_fires_on_new_event(self, mock_process_service_hook): group = self.create_group(project=self.project) event = self.create_event(group=group) hook = self.create_service_hook( project=self.project, organization=self.project.organization, actor=self.user, events=['event.created'], ) with self.feature('projects:servicehooks'): post_process_group( event=event, is_new=False, is_regression=False, is_sample=False, is_new_group_environment=False, ) mock_process_service_hook.delay.assert_called_once_with( servicehook_id=hook.id, event=event, )
def test_execute_rule(self, mock_get_rules, mock_execute_rule): action_id = 'sentry.rules.actions.notify_event.NotifyEventAction' condition_id = 'sentry.rules.conditions.first_seen_event.FirstSeenEventCondition' group = self.create_group(project=self.project) event = self.create_event(group=group) mock_get_rules.return_value = [ Rule( id=1, data={ 'actions': [{'id': action_id}], 'conditions': [{'id': condition_id}], } ) ] post_process_group( group=group, event=event, is_new=False, is_regression=False, is_sample=False, ) mock_get_rules.assert_called_once_with(self.project) assert not mock_execute_rule.delay.called post_process_group( group=group, event=event, is_new=True, is_regression=False, is_sample=False, ) assert len(mock_execute_rule.delay.mock_calls) == 1 post_process_group( group=group, event=event, is_new=True, is_regression=False, is_sample=False, ) assert len(mock_execute_rule.delay.mock_calls) == 2
def test_execute_rule(self, mock_get_rules, mock_execute_rule): action_id = 'sentry.rules.actions.notify_event.NotifyEventAction' condition_id = 'sentry.rules.conditions.first_seen_event.FirstSeenEventCondition' group = self.create_group(project=self.project) event = self.create_event(group=group) mock_get_rules.return_value = [ Rule( id=1, data={ 'actions': [{ 'id': 'sentry.rules.actions.notify_event.NotifyEventAction', }], 'conditions': [{ 'id': 'sentry.rules.conditions.first_seen_event.FirstSeenEventCondition', }], } ), Rule( id=2, data={ 'actions': [{ 'id': 'sentry.rules.actions.notify_event_service.NotifyEventAction', 'service': 'mail', }], 'conditions': [{ 'id': 'sentry.rules.conditions.every_event.EveryEventCondition', }], } ), ] post_process_group( event=event, is_new=False, is_regression=False, is_sample=False, ) mock_get_rules.assert_called_once_with(self.project) assert len(mock_execute_rule.apply_async.mock_calls) == 1 mock_execute_rule.apply_async.reset_mock() post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, ) assert len(mock_execute_rule.apply_async.mock_calls) == 2 mock_execute_rule.apply_async.reset_mock() post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, ) assert len(mock_execute_rule.apply_async.mock_calls) == 2
def test_execute_rule(self, mock_get_rules, mock_execute_rule): action_id = 'sentry.rules.actions.notify_event.NotifyEventAction' condition_id = 'sentry.rules.conditions.first_seen_event.FirstSeenEventCondition' group = self.create_group(project=self.project) event = self.create_event(group=group) mock_get_rules.return_value = [ Rule( id=1, data={ 'actions': [{ 'id': 'sentry.rules.actions.notify_event.NotifyEventAction', }], 'conditions': [{ 'id': 'sentry.rules.conditions.first_seen_event.FirstSeenEventCondition', }], }), Rule( id=2, data={ 'actions': [{ 'id': 'sentry.rules.actions.notify_event_service.NotifyEventAction', 'service': 'mail', }], 'conditions': [{ 'id': 'sentry.rules.conditions.every_event.EveryEventCondition', }], }), ] post_process_group( event=event, is_new=False, is_regression=False, is_sample=False, ) mock_get_rules.assert_called_once_with(self.project) assert len(mock_execute_rule.apply_async.mock_calls) == 1 mock_execute_rule.apply_async.reset_mock() post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, ) assert len(mock_execute_rule.apply_async.mock_calls) == 2 mock_execute_rule.apply_async.reset_mock() post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, ) assert len(mock_execute_rule.apply_async.mock_calls) == 2
def test_execute_rule(self, mock_get_rules, mock_execute_rule): action_id = 'sentry.rules.actions.notify_event.NotifyEventAction' condition_id = 'sentry.rules.conditions.first_seen_event.FirstSeenEventCondition' group = self.create_group(project=self.project) event = self.create_event(group=group) mock_get_rules.return_value = [ Rule(id=1, data={ 'actions': [{ 'id': action_id }], 'conditions': [{ 'id': condition_id }], }) ] post_process_group( group=group, event=event, is_new=False, is_regression=False, is_sample=False, ) assert not mock_execute_rule.delay.called post_process_group( group=group, event=event, is_new=True, is_regression=False, is_sample=False, ) mock_execute_rule.delay.assert_called_once_with( rule_id=1, event=event, is_new=True, is_regression=False, is_sample=False, ) # ensure we dont execute again since the object hasnt changed state post_process_group( group=group, event=event, is_new=True, is_regression=False, is_sample=False, ) assert len(mock_execute_rule.mock_calls) == 1 # and finally test the behavior of cycling back to new post_process_group( group=group, event=event, is_new=False, is_regression=False, is_sample=False, ) post_process_group( group=group, event=event, is_new=True, is_regression=False, is_sample=False, ) assert len(mock_execute_rule.mock_calls) == 2
def test_rule_processor_buffer_values(self): # Test that pending buffer values for `times_seen` are applied to the group and that alerts # fire as expected from sentry.models import Rule MOCK_RULES = ( "sentry.rules.filters.issue_occurrences.IssueOccurrencesFilter", ) redis_buffer = RedisBuffer() with mock.patch("sentry.buffer.get", redis_buffer.get), mock.patch( "sentry.buffer.incr", redis_buffer.incr), patch( "sentry.constants._SENTRY_RULES", MOCK_RULES), patch("sentry.rules.processor.rules", init_registry()) as rules: MockAction = mock.Mock() MockAction.rule_type = "action/event" MockAction.id = "tests.sentry.tasks.post_process.tests.MockAction" MockAction.return_value.after.return_value = [] rules.add(MockAction) conditions = [ { "id": "sentry.rules.filters.issue_occurrences.IssueOccurrencesFilter", "value": 10, }, ] actions = [{ "id": "tests.sentry.tasks.post_process.tests.MockAction" }] Rule.objects.filter(project=self.project).delete() Rule.objects.create(project=self.project, data={ "conditions": conditions, "actions": actions }) event = self.store_event(data={ "message": "testing", "fingerprint": ["group-1"] }, project_id=self.project.id) event_2 = self.store_event(data={ "message": "testing", "fingerprint": ["group-1"] }, project_id=self.project.id) cache_key = write_event_to_cache(event) post_process_group( is_new=True, is_regression=False, is_new_group_environment=True, cache_key=cache_key, group_id=event.group_id, ) event.group.update(times_seen=2) assert MockAction.return_value.after.call_count == 0 cache_key = write_event_to_cache(event_2) buffer.incr(Group, {"times_seen": 15}, filters={"pk": event.group.id}) post_process_group( is_new=True, is_regression=False, is_new_group_environment=True, cache_key=cache_key, group_id=event_2.group_id, ) assert MockAction.return_value.after.call_count == 1
def test_execute_rule(self, mock_get_rules, mock_execute_rule): action_id = 'sentry.rules.actions.notify_event.NotifyEventAction' condition_id = 'sentry.rules.conditions.first_seen_event.FirstSeenEventCondition' group = self.create_group(project=self.project) event = self.create_event(group=group) mock_get_rules.return_value = [ Rule( id=1, data={ 'actions': [{'id': action_id}], 'conditions': [{'id': condition_id}], } ) ] post_process_group( group=group, event=event, is_new=False, is_regression=False, is_sample=False, ) assert not mock_execute_rule.delay.called post_process_group( group=group, event=event, is_new=True, is_regression=False, is_sample=False, ) mock_execute_rule.delay.assert_called_once_with( rule_id=1, event=event, is_new=True, is_regression=False, is_sample=False, ) # ensure we dont execute again since the object hasnt changed state post_process_group( group=group, event=event, is_new=True, is_regression=False, is_sample=False, ) assert len(mock_execute_rule.mock_calls) == 1 # and finally test the behavior of cycling back to new post_process_group( group=group, event=event, is_new=False, is_regression=False, is_sample=False, ) post_process_group( group=group, event=event, is_new=True, is_regression=False, is_sample=False, ) assert len(mock_execute_rule.mock_calls) == 2