Skip to content

Commit a9d44c7

Browse files
committed
feat: Update Group.get_latest_event to use Snuba event
This is the fifth (and final) part of #13905 Group model now uses Snuba Event instead of Postgres Event everywhere.
1 parent ee4d946 commit a9d44c7

File tree

9 files changed

+204
-80
lines changed

9 files changed

+204
-80
lines changed

src/sentry/models/group.py

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@
2121
from django.utils.translation import ugettext_lazy as _
2222

2323
from sentry import eventtypes, tagstore
24-
from sentry.constants import (
25-
DEFAULT_LOGGER_NAME, EVENT_ORDERING_KEY, LOG_LEVELS, MAX_CULPRIT_LENGTH
26-
)
24+
from sentry.constants import DEFAULT_LOGGER_NAME, LOG_LEVELS, MAX_CULPRIT_LENGTH
2725
from sentry.db.models import (
2826
BaseManager, BoundedBigIntegerField, BoundedIntegerField, BoundedPositiveIntegerField,
2927
FlexibleForeignKey, GzippedDictField, Model, sane_repr
@@ -376,20 +374,9 @@ def get_score(self):
376374
return type(self).calculate_score(self.times_seen, self.last_seen)
377375

378376
def get_latest_event(self):
379-
from sentry.models import Event
380-
381377
if not hasattr(self, '_latest_event'):
382-
latest_events = sorted(
383-
Event.objects.filter(
384-
group_id=self.id,
385-
).order_by('-datetime')[0:5],
386-
key=EVENT_ORDERING_KEY,
387-
reverse=True,
388-
)
389-
try:
390-
self._latest_event = latest_events[0]
391-
except IndexError:
392-
self._latest_event = None
378+
self._latest_event = self.get_latest_event_for_environments()
379+
393380
return self._latest_event
394381

395382
def get_latest_event_for_environments(self, environments=()):

tests/sentry/api/endpoints/test_group_integration_details.py

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,44 @@
22

33
import six
44
import mock
5+
from datetime import timedelta
6+
from django.utils import timezone
7+
import copy
58

69
from sentry.integrations.example.integration import ExampleIntegration
710
from sentry.integrations.exceptions import IntegrationError
811
from sentry.models import Activity, ExternalIssue, GroupLink, Integration
912
from sentry.testutils import APITestCase
1013
from sentry.utils.http import absolute_uri
14+
from sentry.testutils.factories import DEFAULT_EVENT_DATA
1115

1216

1317
class GroupIntegrationDetailsTest(APITestCase):
18+
def setUp(self):
19+
super(GroupIntegrationDetailsTest, self).setUp()
20+
self.min_ago = timezone.now() - timedelta(minutes=1)
21+
self.event = self.store_event(
22+
data={
23+
'event_id': 'a' * 32,
24+
'timestamp': self.min_ago.isoformat()[:19],
25+
'message': 'message',
26+
'stacktrace': copy.deepcopy(DEFAULT_EVENT_DATA['stacktrace']),
27+
},
28+
project_id=self.project.id
29+
)
30+
self.group = self.event.group
31+
1432
def test_simple_get_link(self):
1533
self.login_as(user=self.user)
1634
org = self.organization
17-
group = self.create_group()
1835
integration = Integration.objects.create(
1936
provider='example',
2037
name='Example',
2138
)
2239
integration.add_organization(org, self.user)
2340

24-
path = u'/api/0/issues/{}/integrations/{}/?action=link'.format(group.id, integration.id)
41+
path = u'/api/0/issues/{}/integrations/{}/?action=link'.format(
42+
self.group.id, integration.id)
2543

2644
with self.feature('organizations:integrations-issue-basic'):
2745
response = self.client.get(path)
@@ -61,13 +79,12 @@ def test_simple_get_link(self):
6179
def test_simple_get_create(self):
6280
self.login_as(user=self.user)
6381
org = self.organization
64-
group = self.create_group()
65-
self.create_event(group=group)
6682
integration = Integration.objects.create(
6783
provider='example',
6884
name='Example',
6985
)
7086
integration.add_organization(org, self.user)
87+
group = self.group
7188

7289
path = u'/api/0/issues/{}/integrations/{}/?action=create'.format(group.id, integration.id)
7390

@@ -99,7 +116,7 @@ def test_simple_get_create(self):
99116
'required': True,
100117
}, {
101118
'default': ('Sentry Issue: [%s](%s)\n\n```\n'
102-
'Stacktrace (most recent call last):\n\n '
119+
'Stacktrace (most recent call first):\n\n '
103120
'File "sentry/models/foo.py", line 29, in build_msg\n '
104121
'string_max_length=self.string_max_length)\n\nmessage\n```'
105122
) % (group.qualified_short_id, absolute_uri(group.get_absolute_url(params={'referrer': 'example_integration'}))),
@@ -121,15 +138,14 @@ def test_simple_get_create(self):
121138
def test_get_create_with_error(self):
122139
self.login_as(user=self.user)
123140
org = self.organization
124-
group = self.create_group()
125-
self.create_event(group=group)
126141
integration = Integration.objects.create(
127142
provider='example',
128143
name='Example',
129144
)
130145
integration.add_organization(org, self.user)
131146

132-
path = u'/api/0/issues/{}/integrations/{}/?action=create'.format(group.id, integration.id)
147+
path = u'/api/0/issues/{}/integrations/{}/?action=create'.format(
148+
self.group.id, integration.id)
133149

134150
with self.feature('organizations:integrations-issue-basic'):
135151
with mock.patch.object(ExampleIntegration, 'get_create_issue_config', side_effect=IntegrationError('oops')):
@@ -141,15 +157,14 @@ def test_get_create_with_error(self):
141157
def test_get_feature_disabled(self):
142158
self.login_as(user=self.user)
143159
org = self.organization
144-
group = self.create_group()
145-
self.create_event(group=group)
146160
integration = Integration.objects.create(
147161
provider='example',
148162
name='Example',
149163
)
150164
integration.add_organization(org, self.user)
151165

152-
path = u'/api/0/issues/{}/integrations/{}/?action=create'.format(group.id, integration.id)
166+
path = u'/api/0/issues/{}/integrations/{}/?action=create'.format(
167+
self.group.id, integration.id)
153168

154169
with self.feature({'organizations:integrations-issue-basic': False}):
155170
response = self.client.get(path)
@@ -167,7 +182,6 @@ def test_simple_put(self):
167182
integration.add_organization(org, self.user)
168183

169184
path = u'/api/0/issues/{}/integrations/{}/'.format(group.id, integration.id)
170-
171185
with self.feature('organizations:integrations-issue-basic'):
172186
response = self.client.put(path, data={
173187
'externalIssue': 'APP-123'
@@ -367,8 +381,14 @@ def assert_default_project(path, action, expected_project_field):
367381

368382
self.login_as(user=self.user)
369383
org = self.organization
370-
group = self.create_group()
371-
self.create_event(group=group)
384+
event = self.store_event(
385+
data={
386+
'event_id': 'a' * 32,
387+
'timestamp': self.min_ago.isoformat()[:19],
388+
},
389+
project_id=self.project.id
390+
)
391+
group = event.group
372392
integration = Integration.objects.create(
373393
provider='example',
374394
name='Example',

tests/sentry/api/endpoints/test_shared_group_details.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from __future__ import absolute_import, print_function
22

33
import six
4+
from datetime import timedelta
5+
from django.utils import timezone
46

57
from sentry.testutils import APITestCase
68
from sentry.models import GroupShare
@@ -10,8 +12,14 @@ class SharedGroupDetailsTest(APITestCase):
1012
def test_simple(self):
1113
self.login_as(user=self.user)
1214

13-
group = self.create_group()
14-
event = self.create_event(group=group)
15+
min_ago = (timezone.now() - timedelta(minutes=1)).isoformat()[:19]
16+
event = self.store_event(
17+
data={
18+
'timestamp': min_ago,
19+
},
20+
project_id=self.project.id,
21+
)
22+
group = event.group
1523

1624
share_id = group.get_share_id()
1725
assert share_id is None
@@ -29,7 +37,7 @@ def test_simple(self):
2937

3038
assert response.status_code == 200, response.content
3139
assert response.data['id'] == six.text_type(group.id)
32-
assert response.data['latestEvent']['id'] == six.text_type(event.id)
40+
assert response.data['latestEvent']['id'] == six.text_type(event.event_id)
3341
assert response.data['project']['slug'] == group.project.slug
3442
assert response.data['project']['organization']['slug'] == group.organization.slug
3543

tests/sentry/integrations/bitbucket/test_issues.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
from __future__ import absolute_import
22

3+
from datetime import timedelta
4+
import copy
5+
6+
from django.utils import timezone
7+
38
from sentry.integrations.bitbucket.issues import ISSUE_TYPES, PRIORITIES
49
from sentry.models import ExternalIssue, Integration
510
from sentry.testutils import APITestCase
11+
from sentry.testutils.factories import DEFAULT_EVENT_DATA
612

713
import json
814
import responses
@@ -24,8 +30,18 @@ def setUp(self):
2430
'subject': self.subject,
2531
}
2632
)
27-
self.group = self.create_group()
28-
self.create_event(group=self.group)
33+
min_ago = (timezone.now() - timedelta(minutes=1)).isoformat()[:19]
34+
event = self.store_event(
35+
data={
36+
'event_id': 'a' * 32,
37+
'message': 'message',
38+
'timestamp': min_ago,
39+
'stacktrace': copy.deepcopy(DEFAULT_EVENT_DATA['stacktrace']),
40+
41+
},
42+
project_id=self.project.id,
43+
)
44+
self.group = event.group
2945
self.repo_choices = [('myaccount/repo1', 'myaccount/repo1'),
3046
('myaccount/repo2', 'myaccount/repo2')]
3147
self.org_integration = self.integration.add_organization(self.organization)
@@ -203,7 +219,7 @@ def test_get_create_issue_config(self):
203219
}, {
204220
'name': 'description',
205221
'label': 'Description',
206-
'default': u'Sentry Issue: [BAR-1](http://testserver/organizations/baz/issues/%d/?referrer=bitbucket_integration)\n\n```\nStacktrace (most recent call last):\n\n File "sentry/models/foo.py", line 29, in build_msg\n string_max_length=self.string_max_length)\n\nmessage\n```' % self.group.id,
222+
'default': u'Sentry Issue: [BAR-1](http://testserver/organizations/baz/issues/%d/?referrer=bitbucket_integration)\n\n```\nStacktrace (most recent call first):\n\n File "sentry/models/foo.py", line 29, in build_msg\n string_max_length=self.string_max_length)\n\nmessage\n```' % self.group.id,
207223
'type': 'textarea',
208224
'autosize': True,
209225
'maxRows': 10,

tests/sentry/integrations/github/test_issues.py

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import responses
44
import six
5+
from datetime import timedelta
56

67
from mock import patch
78
from exam import fixture
89
from django.test import RequestFactory
10+
from django.utils import timezone
911

1012
from sentry.integrations.github.integration import GitHubIntegration
1113
from sentry.models import Integration, ExternalIssue
@@ -28,6 +30,7 @@ def setUp(self):
2830
)
2931
self.model.add_organization(self.organization, self.user)
3032
self.integration = GitHubIntegration(self.model, self.organization.id)
33+
self.min_ago = (timezone.now() - timedelta(minutes=1)).isoformat()[:19]
3134

3235
@responses.activate
3336
@patch('sentry.integrations.github.client.get_jwt', return_value='jwt_token_1')
@@ -155,8 +158,13 @@ def test_link_issue(self, mock_get_jwt):
155158
@responses.activate
156159
@patch('sentry.integrations.github.client.get_jwt', return_value='jwt_token_1')
157160
def test_repo_dropdown_choices(self, mock_get_jwt):
158-
group = self.create_group()
159-
self.create_event(group)
161+
event = self.store_event(
162+
data={
163+
'event_id': 'a' * 32,
164+
'timestamp': self.min_ago,
165+
},
166+
project_id=self.project.id,
167+
)
160168

161169
responses.add(
162170
responses.POST,
@@ -176,7 +184,7 @@ def test_repo_dropdown_choices(self, mock_get_jwt):
176184
json={'repositories': [{'full_name': 'getsentry/sentry', 'name': 'sentry'}]}
177185
)
178186

179-
resp = self.integration.get_create_issue_config(group=self.group)
187+
resp = self.integration.get_create_issue_config(group=event.group)
180188
assert resp[0]['choices'] == [(u'getsentry/sentry', u'sentry')]
181189

182190
responses.add(
@@ -187,12 +195,12 @@ def test_repo_dropdown_choices(self, mock_get_jwt):
187195

188196
# create an issue
189197
data = {'params': {'repo': 'getsentry/hello'}}
190-
resp = self.integration.get_create_issue_config(group=self.group, **data)
198+
resp = self.integration.get_create_issue_config(group=event.group, **data)
191199
assert resp[0]['choices'] == [(u'getsentry/hello', u'hello'),
192200
(u'getsentry/sentry', u'sentry')]
193201
# link an issue
194202
data = {'params': {'repo': 'getsentry/hello'}}
195-
resp = self.integration.get_link_issue_config(group=self.group, **data)
203+
resp = self.integration.get_link_issue_config(group=event.group, **data)
196204
assert resp[0]['choices'] == [(u'getsentry/hello', u'hello'),
197205
(u'getsentry/sentry', u'sentry')]
198206

@@ -240,8 +248,15 @@ def test_default_repo_link_fields(self, mock_get_jwt):
240248
]
241249
},
242250
)
243-
group = self.create_group()
244-
self.create_event(group=group)
251+
event = self.store_event(
252+
data={
253+
'event_id': 'a' * 32,
254+
'timestamp': self.min_ago,
255+
},
256+
project_id=self.project.id,
257+
)
258+
group = event.group
259+
245260
org_integration = self.integration.org_integration
246261
org_integration.config = {
247262
'project_issue_defaults': {
@@ -278,8 +293,14 @@ def test_default_repo_create_fields(self, mock_get_jwt):
278293
'https://api.github.com/installations/github_external_id/access_tokens',
279294
json={'token': 'token_1', 'expires_at': '2018-10-11T22:14:10Z'}
280295
)
281-
group = self.create_group()
282-
self.create_event(group=group)
296+
event = self.store_event(
297+
data={
298+
'event_id': 'a' * 32,
299+
'timestamp': self.min_ago,
300+
},
301+
project_id=self.project.id,
302+
)
303+
group = event.group
283304
org_integration = self.integration.org_integration
284305
org_integration.config = {
285306
'project_issue_defaults': {
@@ -304,10 +325,14 @@ def test_default_repo_link_fields_no_repos(self, mock_get_jwt):
304325
'repositories': []
305326
},
306327
)
307-
group = self.create_group()
308-
self.create_event(group=group)
309-
310-
fields = self.integration.get_link_issue_config(group)
328+
event = self.store_event(
329+
data={
330+
'event_id': 'a' * 32,
331+
'timestamp': self.min_ago,
332+
},
333+
project_id=self.project.id,
334+
)
335+
fields = self.integration.get_link_issue_config(event.group)
311336
repo_field = [field for field in fields if field['name'] == 'repo'][0]
312337
assert repo_field['default'] is ''
313338
assert repo_field['choices'] == []
@@ -327,11 +352,14 @@ def test_default_repo_create_fields_no_repos(self, mock_get_jwt):
327352
'https://api.github.com/installations/github_external_id/access_tokens',
328353
json={'token': 'token_1', 'expires_at': '2018-10-11T22:14:10Z'}
329354
)
330-
331-
group = self.create_group()
332-
self.create_event(group=group)
333-
334-
fields = self.integration.get_create_issue_config(group)
355+
event = self.store_event(
356+
data={
357+
'event_id': 'a' * 32,
358+
'timestamp': self.min_ago,
359+
},
360+
project_id=self.project.id,
361+
)
362+
fields = self.integration.get_create_issue_config(event.group)
335363
repo_field = [field for field in fields if field['name'] == 'repo'][0]
336364
assignee_field = [field for field in fields if field['name'] == 'assignee'][0]
337365

0 commit comments

Comments
 (0)