def test_stacktrace_wins_over_http(http_comp_hash, stack_comp_hash): # this was a regression, and a very important one http_comp_hash.return_value = [['baz']] stack_comp_hash.return_value = [['foo', 'bar']] event = Event( data={ 'stacktrace': { 'frames': [{ 'lineno': 1, 'filename': 'foo.py', }], }, 'request': { 'url': 'http://example.com' }, }, platform='python', message='Foo bar', ) hashes = event.get_hashes() assert len(hashes) == 1 hash_one = hashes[0] stack_comp_hash.assert_called_once_with('python') assert not http_comp_hash.called assert hash_one == md5_from_hash(['foo', 'bar'])
def new_event(request): platform = request.GET.get("platform", "python") 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(platform)) 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))) return 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, "tags": [("logger", "javascript"), ("environment", "prod"), ("level", "error"), ("device", "Other")], }, ).render()
def create_event(self, event_id=None, **kwargs): if event_id is None: event_id = uuid4().hex if 'group' not in kwargs: kwargs['group'] = self.group kwargs.setdefault('project', kwargs['group'].project) kwargs.setdefault('data', copy.deepcopy(DEFAULT_EVENT_DATA)) if kwargs.get('tags'): tags = kwargs.pop('tags') if isinstance(tags, dict): tags = tags.items() kwargs['data']['tags'] = tags kwargs['data'].setdefault('errors', [{ 'type': EventError.INVALID_DATA, 'name': 'foobar', }]) event = Event( event_id=event_id, **kwargs ) EventMapping.objects.create( project_id=event.project.id, event_id=event_id, group=event.group, ) # emulate EventManager refs event.data.bind_ref(event) event.save() return event
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 create_event(self, event_id=None, **kwargs): if event_id is None: event_id = uuid4().hex if 'group' not in kwargs: kwargs['group'] = self.group kwargs.setdefault('project', kwargs['group'].project) kwargs.setdefault('message', kwargs['group'].message) kwargs.setdefault('data', LEGACY_DATA.copy()) if kwargs.get('tags'): tags = kwargs.pop('tags') if isinstance(tags, dict): tags = tags.items() kwargs['data']['tags'] = tags kwargs['data'].setdefault('errors', [{ 'type': EventError.INVALID_DATA, 'name': 'foobar', }]) event = Event( event_id=event_id, **kwargs ) # emulate EventManager refs event.data.bind_ref(event) event.save() return event
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_event_hash_variant(infile): with open(os.path.join(_fixture_path, infile + '.json')) as f: input = json.load(f) with open(os.path.join(_fixture_path, infile + '.out')) as f: refval = f.read().decode('utf-8').rstrip() mgr = EventManager(data=input) mgr.normalize() evt = Event(data=mgr.get_data()) rv = [] for (key, value) in sorted(evt.get_grouping_variants().items()): if rv: rv.append('-' * 74) rv.append('%s:' % key) dump_variant(value, rv, 1) output = '\n'.join(rv) if not refval: log(output) log(repr(evt.get_hashes())) assert sorted(evt.get_hashes()) == sorted( filter(None, [x.get_hash() for x in evt.get_grouping_variants().values()])) assert refval == output
def test_notify_users_with_owners(self): event_all_users = Event( group=self.group, message=self.group.message, project=self.project, datetime=self.group.last_seen, data=self.make_event_data('foo.cbl'), ) self.assert_notify(event_all_users, [self.user.email, self.user2.email]) event_team = Event( group=self.group, message=self.group.message, project=self.project, datetime=self.group.last_seen, data=self.make_event_data('foo.py'), ) self.assert_notify(event_team, [self.user.email, self.user2.email]) event_single_user = Event( group=self.group, message=self.group.message, project=self.project, datetime=self.group.last_seen, data=self.make_event_data('foo.jx'), ) self.assert_notify(event_single_user, [self.user2.email]) # Make sure that disabling mail alerts works as expected UserOption.objects.set_value( user=self.user2, key='mail:alert', value=0, project=self.project ) event_all_users = Event( group=self.group, message=self.group.message, project=self.project, datetime=self.group.last_seen, data=self.make_event_data('foo.cbl'), ) self.assert_notify(event_all_users, [self.user.email])
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, event=event, project=event.project, type=Activity.ASSIGNED, user=request.user, data={'text': 'This is an example note!'}, ) 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_simple(self): configure_sdk() Hub.current.bind_client(Hub.main.client) with self.tasks(): event_id = raven.captureMessage("internal client test") event = nodestore.get( Event.generate_node_id(settings.SENTRY_PROJECT, event_id)) assert event["project"] == settings.SENTRY_PROJECT assert event["event_id"] == event_id assert event["logentry"]["formatted"] == "internal client test"
def get_child_relations_bulk(self, instance_list): from sentry.models import Event node_ids = [] for i in instance_list: node_id = Event.generate_node_id(i.project_id, i.event_id) node_ids.append(node_id) # Unbind the NodeField so it doesn't attempt to get # get deleted a second time after NodeDeletionTask # runs, when the Event itself is deleted. i.data = None return [BaseRelation({"nodes": node_ids}, NodeDeletionTask)]
def create_event(self, event_id=None, **kwargs): if event_id is None: event_id = uuid4().hex if 'group' not in kwargs: kwargs['group'] = self.group kwargs.setdefault('project', kwargs['group'].project) kwargs.setdefault('message', kwargs['group'].message) kwargs.setdefault('data', LEGACY_DATA.copy()) if kwargs.get('tags'): tags = kwargs.pop('tags') if isinstance(tags, dict): tags = tags.items() kwargs['data']['tags'] = tags event = Event( event_id=event_id, **kwargs ) # emulate EventManager refs event.data.bind_ref(event) event.save() return event
def inner(data): mgr = EventManager(data={"stacktrace": data}) mgr.normalize() evt = Event(data=mgr.get_data()) interface = evt.interfaces.get('stacktrace') insta_snapshot({ 'errors': evt.data.get('errors'), 'to_json': interface and interface.to_json(), 'get_stacktrace': interface and interface.get_stacktrace(evt), 'to_string': interface and interface.to_string(evt), })
def test_get_stacktrace_with_module(self): event = mock.Mock(spec=Event()) interface = Stacktrace.to_python( dict(frames=[{ 'module': 'foo' }, { 'module': 'bar' }])) result = interface.get_stacktrace(event) self.assertEquals( result, 'Stacktrace (most recent call last):\n\n Module "foo"\n Module "bar"' )
def group_event_details_json(request, team, project, group_id, event_id_or_latest): group = get_object_or_404(Group, pk=group_id, project=project) if event_id_or_latest == 'latest': # It's possible that a message would not be created under certain # circumstances (such as a post_save signal failing) event = group.get_latest_event() or Event() else: event = get_object_or_404(group.event_set, pk=event_id_or_latest) return HttpResponse(json.dumps(event.as_dict()), mimetype='application/json')
def test_to_html_render_call(self, render_to_string, get_traceback): event = mock.Mock(spec=Event()) get_traceback.return_value = 'bar' interface = Stacktrace(frames=[{'lineno': 1, 'filename': 'foo.py'}]) result = interface.to_html(event) get_traceback.assert_called_once_with(event, newest_first=False) render_to_string.assert_called_once_with('sentry/partial/interfaces/stacktrace.html', { 'event': event, 'frames': [{'function': None, 'abs_path': None, 'start_lineno': None, 'lineno': 1, 'context': [], 'vars': [], 'in_app': True, 'filename': 'foo.py'}], 'stacktrace': 'bar', 'system_frames': 0, 'newest_first': False, }) self.assertEquals(result, render_to_string.return_value)
def get(self, request, organization, project, team, group_id, event_id_or_latest): group = get_object_or_404(Group, pk=group_id, project=project) if event_id_or_latest == 'latest': # It's possible that a message would not be created under certain # circumstances (such as a post_save signal failing) event = group.get_latest_event() or Event(group=group) else: event = get_object_or_404(group.event_set, pk=event_id_or_latest) Event.objects.bind_nodes([event], 'data') GroupMeta.objects.populate_cache([group]) return HttpResponse(json.dumps(event.as_dict()), mimetype='application/json')
def test_get_stacktrace_with_filename_and_function(self): event = mock.Mock(spec=Event()) interface = Stacktrace(frames=[{ 'filename': 'foo', 'function': 'biz' }, { 'filename': 'bar', 'function': 'baz' }]) result = interface.get_stacktrace(event) self.assertEquals( result, 'Stacktrace (most recent call last):\n\n File "foo", in biz\n File "bar", in baz' )
def inner(data): mgr = EventManager(data={"threads": data}) mgr.normalize() evt = Event(data=mgr.get_data()) interface = evt.interfaces.get("threads") insta_snapshot({ "errors": evt.data.get("errors"), "to_json": interface and interface.to_json(), "api_context": interface and interface.get_api_context(), })
def build_event(frames): return Event( data={ 'sentry.interfaces.Exception': { 'values': [ { 'stacktrace': { 'frames': frames, }, }, ], }, }, )
def inner(data): mgr = EventManager(data={"csp": data}) mgr.normalize() evt = Event(data=mgr.get_data()) interface = evt.interfaces.get("csp") insta_snapshot({ "errors": evt.data.get("errors"), "to_json": interface and interface.to_json(), "message": interface and interface.get_message(), "culprit": interface and interface.get_culprit(), "origin": interface and interface.get_origin(), "tags": interface and interface.get_tags(), })
def test_event_hash_variant(insta_snapshot, config_name, test_name, log): with open(os.path.join(_fixture_path, test_name + '.json')) as f: input = json.load(f) grouping_config = { 'id': config_name, } mgr = EventManager(data=input, grouping_config=grouping_config) mgr.normalize() data = mgr.get_data() evt = Event(data=data, platform=data['platform']) rv = [] for (key, value) in sorted(evt.get_grouping_variants().items()): if rv: rv.append('-' * 74) rv.append('%s:' % key) dump_variant(value, rv, 1) output = '\n'.join(rv) log(repr(evt.get_hashes())) assert evt.get_grouping_config() == grouping_config insta_snapshot(output)
def group(request, project, group): # It's possible that a message would not be created under certain # circumstances (such as a post_save signal failing) event = group.get_latest_event() or Event(group=group) return render_to_response('sentry/groups/details.html', { 'project': project, 'page': 'details', 'group': group, 'event': event, 'interface_list': _get_rendered_interfaces(event), 'json_data': event.data.get('extra', {}), 'version_data': event.data.get('modules', None), 'can_admin_event': can_admin_group(request.user, group), }, request)
def inner(data): mgr = EventManager(data={"csp": data}) mgr.normalize() evt = Event(data=mgr.get_data()) interface = evt.interfaces.get('csp') insta_snapshot({ 'errors': evt.data.get('errors'), 'to_json': interface and interface.to_json(), 'message': interface and interface.get_message(), 'culprit': interface and interface.get_culprit(), 'origin': interface and interface.get_origin(), 'tags': interface and interface.get_tags() })
def new_note(request): team = Team( id=1, slug='example', name='Example', ) project = Project( id=1, slug='example', name='Example', team=team, ) 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/new_note.html', text_template='sentry/emails/new_note.txt', context={ 'text': note.data['text'], '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 test_get_send_to_with_user_owners(self): event = Event( group=self.group, message=self.group.message, project=self.project, datetime=self.group.last_seen, data=self.make_event_data('foo.cbl') ) assert (sorted(set([self.user.pk, self.user2.pk])) == sorted( self.plugin.get_send_to(self.project, event.data))) # Make sure that disabling mail alerts works as expected UserOption.objects.set_value( user=self.user2, key='mail:alert', value=0, project=self.project ) assert set([self.user.pk]) == self.plugin.get_send_to(self.project, event.data)
def render_with_group_context(group, template, context, request=None): # It's possible that a message would not be created under certain # circumstances (such as a post_save signal failing) event = group.get_latest_event() or Event() event.group = group context.update({ 'project': group.project, 'group': group, 'event': event, 'json_data': event.data.get('extra', {}), 'version_data': event.data.get('modules', None), 'can_admin_event': can_admin_group(request.user, group), }) return render_to_response(template, context, request)
def test_dupe_message_id(self, eventstream_insert): # Saves the latest event to nodestore and eventstream project_id = 1 event_id = "a" * 32 node_id = Event.generate_node_id(project_id, event_id) manager = EventManager(make_event(event_id=event_id, message="first")) manager.normalize() manager.save(project_id) assert nodestore.get(node_id)["logentry"]["formatted"] == "first" manager = EventManager(make_event(event_id=event_id, message="second")) manager.normalize() manager.save(project_id) assert nodestore.get(node_id)["logentry"]["formatted"] == "second" assert eventstream_insert.call_count == 2
def test_encoding(self): configure_sdk() Hub.current.bind_client(Hub.main.client) class NotJSONSerializable: pass with self.tasks(): event_id = raven.captureMessage( "check the req", extra={"request": NotJSONSerializable()}) event = nodestore.get( Event.generate_node_id(settings.SENTRY_PROJECT, event_id)) assert event["project"] == settings.SENTRY_PROJECT assert event["logentry"]["formatted"] == "check the req" assert "NotJSONSerializable" in event["extra"]["request"]
def group(request, team, project, group, event_id=None): # It's possible that a message would not be created under certain # circumstances (such as a post_save signal failing) activity_qs = Activity.objects.order_by('-datetime').select_related('user') if event_id: event = get_object_or_404(group.event_set, id=event_id) activity_qs = activity_qs.filter( Q(event=event) | Q(event__isnull=True), ) else: event = group.get_latest_event() or Event() # bind params to group in case they get hit event.group = group event.project = project # filter out dupes activity_items = set() activity = [] for item in activity_qs.filter(group=group)[:10]: sig = (item.event_id, item.type, item.ident, item.user_id) if sig not in activity_items: activity_items.add(sig) activity.append(item) # trim to latest 5 activity = activity[:5] context = { 'page': 'details', 'activity': activity, } is_public = group_is_public(group, request.user) if is_public: template = 'sentry/groups/public_details.html' context['PROJECT_LIST'] = [project] else: template = 'sentry/groups/details.html' return render_with_group_context(group, template, context, request, event=event, is_public=is_public)
def inner(data): mgr = EventManager(data={"exception": data}) mgr.normalize() evt = Event(data=mgr.get_data()) interface = evt.interfaces.get('exception') insta_snapshot({ 'errors': evt.data.get('errors'), 'to_json': interface and interface.to_json(), 'get_api_context': interface and interface.get_api_context(), 'to_string': interface and interface.to_string(evt), })
def inner(data): mgr = EventManager(data={"stacktrace": data}) mgr.normalize() evt = Event(data=mgr.get_data()) interface = evt.interfaces.get("stacktrace") insta_snapshot({ "errors": evt.data.get("errors"), "to_json": interface and interface.to_json(), "get_stacktrace": interface and interface.get_stacktrace(evt), "to_string": interface and interface.to_string(evt), })
def test_simple(self): event_id = "a" * 32 project = self.create_project() node_id = Event.generate_node_id(project.id, event_id) group = self.create_group(project=project) event = self.create_event(group=group, event_id=event_id) EventAttachment.objects.create( event_id=event.event_id, project_id=event.project_id, file=File.objects.create(name="hello.png", type="image/png"), name="hello.png", ) UserReport.objects.create(event_id=event.event_id, project_id=event.project_id, name="Jane Doe") key = "key" value = "value" tk = tagstore.create_tag_key(project_id=project.id, environment_id=self.environment.id, key=key) tv = tagstore.create_tag_value(project_id=project.id, environment_id=self.environment.id, key=key, value=value) tagstore.create_event_tags( event_id=event.id, group_id=group.id, project_id=project.id, environment_id=self.environment.id, tags=[(tk.key, tv.value)], ) assert nodestore.get(node_id) is not None deletion = ScheduledDeletion.schedule(event, days=0) deletion.update(in_progress=True) with self.tasks(): run_deletion(deletion.id) assert not Event.objects.filter(id=event.id).exists() assert not EventAttachment.objects.filter( event_id=event.event_id, project_id=project.id).exists() assert not UserReport.objects.filter(event_id=event.event_id, project_id=project.id).exists() assert not EventTag.objects.filter(event_id=event.id).exists() assert nodestore.get(node_id) is None
def get(self, request): org = Organization( id=1, slug='organization', name='My Company', ) team = Team( id=1, slug='team', name='My Team', organization=org, ) project = Project( id=1, organization=org, team=team, slug='project', name='My Project', ) group = next( make_group_generator( get_random(request), project, ), ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), datetime=datetime(2016, 6, 13, 3, 8, 24, tzinfo=timezone.utc), ) activity = Activity( group=event.group, project=event.project, **self.get_activity(request, event) ) return render_to_response('sentry/debug/mail/preview.html', { 'preview': ActivityMailPreview(activity), 'format': request.GET.get('format'), })