def make_group_generator(random, project): epoch = to_timestamp(datetime(2016, 6, 1, 0, 0, 0, tzinfo=timezone.utc)) for id in itertools.count(1): first_seen = epoch + random.randint(0, 60 * 60 * 24 * 30) last_seen = random.randint(first_seen, first_seen + (60 * 60 * 24 * 30)) culprit = make_culprit(random) level = random.choice(LOG_LEVELS.keys()) message = make_message(random) group = Group( id=id, project=project, culprit=culprit, level=level, message=message, first_seen=to_datetime(first_seen), last_seen=to_datetime(last_seen), status=random.choice((GroupStatus.UNRESOLVED, GroupStatus.RESOLVED)), data={"type": "default", "metadata": {"title": message}}, ) if random.random() < 0.8: group.data = make_group_metadata(random, group) yield group
def test_notify_users_renders_interfaces_with_utf8(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) stacktrace = Mock(spec=Stacktrace) stacktrace.to_string.return_value = u'רונית מגן' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.message = 'hello world' event.logger = 'root' event.site = None event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} with self.Settings(SENTRY_URL_PREFIX='http://example.com'): p = MailProcessor(send_to=['*****@*****.**']) p.notify_users(group, event) stacktrace.get_title.assert_called_once_with() stacktrace.to_string.assert_called_once_with(event)
def test_multiline_error(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message='hello world\nfoo bar', logger='root', ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, ) notification = Notification(event=event) with self.settings(SENTRY_URL_PREFIX='http://example.com'): self.plugin.notify(notification) _send_mail.assert_called_once() args, kwargs = _send_mail.call_args assert kwargs.get('subject') == u"[{0} {1}] ERROR: hello world".format( self.team.name, self.project.name)
def test_multiline_error(self, _send_mail): event_manager = EventManager({"message": "hello world\nfoo bar", "level": "error"}) event_manager.normalize() event_data = event_manager.get_data() event_type = event_manager.get_event_type() event_data["type"] = event_type.key event_data["metadata"] = event_type.get_metadata(event_data) group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message=event_manager.get_search_message(), logger="root", short_id=2, data={"type": event_type.key, "metadata": event_type.get_metadata(event_data)}, ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, data=event_data, ) notification = Notification(event=event) with self.options({"system.url-prefix": "http://example.com"}): self.plugin.notify(notification) assert _send_mail.call_count is 1 args, kwargs = _send_mail.call_args assert kwargs.get("subject") == u"BAR-2 - hello world"
def new_event(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', level=logging.ERROR, ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) rule = Rule(label="An example rule") interface_list = [] for interface in event.interfaces.itervalues(): body = interface.to_email_html(event) if not body: continue interface_list.append((interface.get_title(), mark_safe(body))) preview = MailPreview( html_template='sentry/emails/error.html', text_template='sentry/emails/error.html', context={ 'rule': rule, 'group': group, 'event': event, 'link': 'http://example.com/link', 'interfaces': interface_list, 'tags': event.get_tags(), 'project_label': project.name, }, ) return render_to_response('sentry/debug/mail/preview.html', { 'preview': preview, })
def test_notify_users_does_email(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message='hello world', logger='root', ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, ) notification = Notification(event=event) with self.options({'system.url-prefix': 'http://example.com'}): self.plugin.notify(notification) assert _send_mail.call_count is 1 args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get('project'), self.project) self.assertEquals(kwargs.get('group'), group) assert kwargs.get('subject') == u"[{0} {1}] ERROR: hello world".format( self.team.name, self.project.name)
def test_notify_users_renders_interfaces_with_utf8(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) stacktrace = Mock(spec=Stacktrace) stacktrace.to_email_html.return_value = u'רונית מגן' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.project = self.project event.message = 'hello world' event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} notification = Notification(event=event) with self.settings(SENTRY_URL_PREFIX='http://example.com'): self.plugin.notify(notification) stacktrace.get_title.assert_called_once_with() stacktrace.to_email_html.assert_called_once_with(event)
def test_notify_users_does_email(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message='hello world', logger='root', short_id=2, ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, data={'tags': [ ('level', 'error'), ]}, ) notification = Notification(event=event) with self.options({'system.url-prefix': 'http://example.com'}): self.plugin.notify(notification) assert _send_mail.call_count is 1 args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get('project'), self.project) self.assertEquals(kwargs.get('reference'), group) assert kwargs.get('subject') == u'BAR-2 - hello world'
def test_multiline_error(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message='hello world\nfoo bar', logger='root', ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, data={ 'tags': [ ('level', 'error'), ] }, ) notification = Notification(event=event) with self.options({'system.url-prefix': 'http://example.com'}): self.plugin.notify(notification) assert _send_mail.call_count is 1 args, kwargs = _send_mail.call_args assert kwargs.get('subject') == u"[{0} {1}] ERROR: hello world".format( self.team.name, self.project.name)
def test_notify_users_renders_interfaces_with_utf8_fix_issue_422(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) stacktrace = Mock(spec=Stacktrace) stacktrace.to_email_html.return_value = u'רונית מגן' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.project = self.project event.message = 'Soubor ji\xc5\xbe existuje' event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} notification = Notification(event=event) with self.options({'system.url-prefix': 'http://example.com'}): self.plugin.notify(notification) stacktrace.get_title.assert_called_once_with() stacktrace.to_email_html.assert_called_once_with(event)
def test_notify_users_does_email(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) event = Event( group=group, message='hello world', logger='root', project=self.project, datetime=group.last_seen, ) with self.Settings(SENTRY_URL_PREFIX='http://example.com'): self.plugin.notify_users(group, event) _send_mail.assert_called_once() args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get('fail_silently'), False) self.assertEquals(kwargs.get('project'), self.project) assert kwargs.get('subject') == u"[{0}] ERROR: hello world".format( self.project.name)
def test_notify_users_does_email(self, _send_mail): project = Project(id=1, name='Project Name') group = Group() group.first_seen = timezone.now() group.last_seen = group.first_seen group.project = project group.id = 2 event = Event() event.group = group event.message = 'hello world' event.logger = 'root' event.project = project event.date = group.last_seen with self.Settings(SENTRY_URL_PREFIX='http://example.com'): p = MailProcessor(send_to=['*****@*****.**']) p.notify_users(group, event) _send_mail.assert_called_once() args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get('fail_silently'), False) self.assertEquals(kwargs.get('project'), project) self.assertEquals(kwargs.get('subject'), u"[Project Name] ERROR: hello world")
def test_notify_users_renders_interfaces(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) stacktrace = Mock(spec=Stacktrace) stacktrace.to_email_html.return_value = 'foo bar' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.project = self.project event.message = 'hello world' event.logger = 'root' event.site = None event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} with self.settings(SENTRY_URL_PREFIX='http://example.com'): self.plugin.notify_users(group, event) stacktrace.get_title.assert_called_once_with() stacktrace.to_email_html.assert_called_once_with(event)
def test_notify_users_renders_interfaces_with_utf8_fix_issue_422( self, _send_mail): group = Group() group.first_seen = datetime.datetime.now() group.last_seen = group.first_seen group.id = 2 group.project_id = 1 stacktrace = Mock(spec=Stacktrace) stacktrace.to_string.return_value = u'רונית מגן' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.message = 'Soubor ji\xc5\xbe existuje' event.logger = 'root' event.site = None event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} with self.Settings(SENTRY_URL_PREFIX='http://example.com'): p = MailProcessor(send_to=['*****@*****.**']) p.notify_users(group, event) stacktrace.get_title.assert_called_once_with() stacktrace.to_string.assert_called_once_with(event)
def test_get_group_backfill_attributes(self): now = datetime.utcnow().replace(microsecond=0, tzinfo=timezone.utc) assert get_group_backfill_attributes( get_caches(), Group( active_at=now, first_seen=now, last_seen=now, platform="javascript", message="Hello from JavaScript", level=logging.INFO, score=Group.calculate_score(3, now), logger="javascript", times_seen=1, first_release=None, culprit="", data={ "type": "default", "last_received": to_timestamp(now), "metadata": {} }, ), [ self.store_event( data={ "platform": "python", "message": "Hello from Python", "timestamp": iso_format(now - timedelta(hours=1)), "type": "default", "level": "debug", "tags": { "logger": "java" }, }, project_id=self.project.id, ), self.store_event( data={ "platform": "java", "message": "Hello from Java", "timestamp": iso_format(now - timedelta(hours=2)), "type": "default", "level": "debug", "tags": { "logger": "java" }, }, project_id=self.project.id, ), ], ) == { "active_at": now - timedelta(hours=2), "first_seen": now - timedelta(hours=2), "platform": "java", "score": Group.calculate_score(3, now), "logger": "java", "times_seen": 3, "first_release": None, }
def test_notify_users_renders_interfaces_with_utf8_fix_issue_422( self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) stacktrace = Mock(spec=Stacktrace) stacktrace.to_string.return_value = u'רונית מגן' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.message = 'Soubor ji\xc5\xbe existuje' event.logger = 'root' event.site = None event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} with self.Settings(SENTRY_URL_PREFIX='http://example.com'): self.plugin.notify_users(group, event) stacktrace.get_title.assert_called_once_with() stacktrace.to_string.assert_called_once_with(event)
def test_get_group_backfill_attributes(self): now = datetime(2017, 5, 3, 6, 6, 6, tzinfo=pytz.utc) assert get_group_backfill_attributes( get_caches(), Group( active_at=now, first_seen=now, last_seen=now, platform='javascript', message='Hello from JavaScript', level=logging.INFO, score=ScoreClause.calculate(3, now), logger='javascript', times_seen=1, first_release=None, culprit='', data={ 'type': 'default', 'last_received': to_timestamp(now), 'metadata': {}, }, ), [ Event( platform='python', message='Hello from Python', datetime=now - timedelta(hours=1), data={ 'type': 'default', 'metadata': {}, 'tags': [ ['level', 'error'], ['logger', 'python'], ], }, ), Event( platform='java', message='Hello from Java', datetime=now - timedelta(hours=2), data={ 'type': 'default', 'metadata': {}, 'tags': [ ['level', 'debug'], ['logger', 'java'], ], }, ), ], ) == { 'active_at': now - timedelta(hours=2), 'first_seen': now - timedelta(hours=2), 'platform': 'java', 'score': ScoreClause.calculate(3, now), 'logger': 'java', 'times_seen': 3, 'first_release': None, }
def test_process_does_save_call_with_results(self, process): group = Group(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} self.buffer._tnt.insert(self.sentry_space, ('foo', 2, 0L)) self.buffer.process(Group, columns, filters) process.assert_called_once_with(Group, {'times_seen': 2}, filters, None)
def test_process_does_clear_buffer(self, process): group = Group(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} self.buffer._tnt.insert(self.sentry_space, ('foo', 2, 0L)) self.buffer.process(Group, columns, filters) response = self.buffer._tnt.select(self.sentry_space, ['foo']) self.assertEquals(int(response[0][1]), 0)
def create_event(data, group_id=123): mgr = EventManager(data=data, grouping_config=get_default_grouping_config_dict()) mgr.normalize() data = mgr.get_data() evt = eventstore.create_event(data=data) evt.project = project = Project(id=123) evt.group = Group(id=group_id, project=project) return evt
def new_note(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) note = Activity( group=event.group, event=event, project=event.project, type=Activity.NOTE, user=request.user, data={'text': 'This is an example note!'}, ) preview = MailPreview( html_template='sentry/emails/activity/note.html', text_template='sentry/emails/activity/note.txt', context={ 'data': note.data, 'author': note.user, 'date': note.datetime, 'group': group, 'link': group.get_absolute_url(), }, ) return render_to_response('sentry/debug/mail/preview.html', { 'preview': preview, })
def assigned(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) assigned = Activity( group=event.group, project=event.project, type=Activity.ASSIGNED, user=request.user, data={ 'text': 'This is an example note!', 'assignee': '*****@*****.**' }, ) return MailPreview( html_template='sentry/emails/activity/assigned.html', text_template='sentry/emails/activity/assigned.txt', context={ 'data': assigned.data, 'author': assigned.user, 'date': assigned.datetime, 'group': group, 'link': group.get_absolute_url(), }, ).render()
def test_get_group_backfill_attributes(self): now = datetime(2017, 5, 3, 6, 6, 6, tzinfo=pytz.utc) assert get_group_backfill_attributes( get_caches(), Group( active_at=now, first_seen=now, last_seen=now, platform="javascript", message="Hello from JavaScript", level=logging.INFO, score=Group.calculate_score(3, now), logger="javascript", times_seen=1, first_release=None, culprit="", data={ "type": "default", "last_received": to_timestamp(now), "metadata": {} }, ), [ Event( platform="python", message="Hello from Python", datetime=now - timedelta(hours=1), data={ "type": "default", "metadata": {}, "tags": [["level", "error"], ["logger", "python"]], }, ), Event( platform="java", message="Hello from Java", datetime=now - timedelta(hours=2), data={ "type": "default", "metadata": {}, "tags": [["level", "debug"], ["logger", "java"]], }, ), ], ) == { "active_at": now - timedelta(hours=2), "first_seen": now - timedelta(hours=2), "platform": "java", "score": Group.calculate_score(3, now), "logger": "java", "times_seen": 3, "first_release": None, }
def test_similarity_extract_fingerprinting(fingerprint_input, insta_snapshot): similarity = sentry.similarity.features2 _, evt = fingerprint_input.create_event(get_default_grouping_config_dict()) evt.project = project = Project(id=123) evt.group = Group(id=123, project=project) snapshot = [] for label, features in similarity.extract(evt).items(): for feature in features: snapshot.append("{}: {}".format(":".join(label), json.dumps(feature, sort_keys=True))) insta_snapshot("\n".join(sorted(snapshot)))
def test_redirects_to_stream_if_has_groups(self): self.login_as(self.user) manager = ManagerMock(Group.objects, Group()) with mock.patch('sentry.models.Group.objects', manager): resp = self.client.get(self.path) manager.assert_chain_calls(mock.call.filter(project=self.project), ) manager.exists.assert_called_once_with() assert resp.status_code == 302 assert resp['Location'] == 'http://testserver' + reverse( 'sentry-stream', args=[self.project.slug])
def test_get_groups_for_query(self): organization = Organization(id=1, slug="organization", name="My Company") project_0 = Project(id=100, organization=organization) project_1 = Project(id=101, organization=organization) project_2 = Project(id=102, organization=organization) groups_by_project = { project_0: {Group(id=10, project=project_0), Group(id=11, project=project_0)}, project_1: {Group(id=12, project=project_0)}, project_2: {Group(id=13, project=project_0)}, } notification_settings_by_scope = { NotificationScopeType.PROJECT: { project_0.id: { ExternalProviders.SLACK: NotificationSettingOptionValues.NEVER, ExternalProviders.EMAIL: NotificationSettingOptionValues.ALWAYS, }, project_1.id: { ExternalProviders.SLACK: NotificationSettingOptionValues.NEVER, ExternalProviders.EMAIL: NotificationSettingOptionValues.NEVER, }, } } query_groups = get_groups_for_query(groups_by_project, notification_settings_by_scope, user=self.user) assert {group.id for group in query_groups} == {10, 11, 13}
def test_process_saves_extra(self, process): group = Group(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} the_date = (timezone.now() + timedelta(days=5)).replace(microsecond=0) self.buffer._tnt.insert(self.sentry_space, ('foo', 1, 0L)) self.buffer._tnt.insert( self.sentry_extra_space, ('extra', 'last_seen', pickle.dumps(the_date), 0L)) self.buffer.process(Group, columns, filters) process.assert_called_once_with(Group, columns, filters, {'last_seen': the_date}) lua_code = 'return box.space[%s]:len()' % (self.sentry_extra_space, ) response = self.buffer._tnt.call('box.dostring', lua_code) self.assertEqual(0, int(response[0][0]))
def test_notify_users_does_email(self, _send_mail): event_manager = EventManager({ 'message': 'hello world', 'level': 'error', }) event_manager.normalize() event_data = event_manager.get_data() event_type = event_manager.get_event_type() event_data['type'] = event_type.key event_data['metadata'] = event_type.get_metadata(event_data) group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message=event_manager.get_search_message(), logger='root', short_id=2, data={ 'type': event_type.key, 'metadata': event_type.get_metadata(event_data), } ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, data=event_data ) notification = Notification(event=event) with self.options({'system.url-prefix': 'http://example.com'}): self.plugin.notify(notification) assert _send_mail.call_count is 1 args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get('project'), self.project) self.assertEquals(kwargs.get('reference'), group) assert kwargs.get('subject') == u'BAR-2 - hello world'
def setUp(self) -> None: self.user = User(id=1) self.project = Project(id=123) self.group = Group(id=456, project=self.project) self.notification_settings = [ NotificationSetting( provider=ExternalProviders.SLACK.value, type=NotificationSettingTypes.WORKFLOW.value, value=NotificationSettingOptionValues.ALWAYS.value, target=self.user.actor, scope_type=NotificationScopeType.PROJECT.value, scope_identifier=self.project.id, ), NotificationSetting( provider=ExternalProviders.SLACK.value, type=NotificationSettingTypes.WORKFLOW.value, value=NotificationSettingOptionValues.ALWAYS.value, target=self.user.actor, scope_type=NotificationScopeType.USER.value, scope_identifier=self.user.id, ), ]
class DashboardTest(TestCase): @fixture def path(self): return reverse('sentry', args=[self.project.id]) def test_requires_authentication(self): self.assertRequiresAuthentication(self.path) def test_redirects_to_getting_started_if_no_groups(self): self.login_as(self.user) manager = ManagerMock(Group.objects) with mock.patch('sentry.models.Group.objects', manager): resp = self.client.get(self.path) manager.assert_chain_calls(mock.call.filter(project=self.project), ) manager.exists.assert_called_once_with() assert resp.status_code == 302 assert resp['Location'] == 'http://testserver' + reverse( 'sentry-get-started', args=[self.project.slug]) @mock.patch('sentry.models.Group.objects', ManagerMock(Group.objects, Group())) def test_redirects_to_stream_if_has_groups(self): self.login_as(self.user) manager = ManagerMock(Group.objects, Group()) with mock.patch('sentry.models.Group.objects', manager): resp = self.client.get(self.path) manager.assert_chain_calls(mock.call.filter(project=self.project), ) manager.exists.assert_called_once_with() assert resp.status_code == 302 assert resp['Location'] == 'http://testserver' + reverse( 'sentry-stream', args=[self.project.slug])