123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- from __future__ import absolute_import
- from datetime import datetime, timedelta
- import pytest
- import time
- import uuid
- from sentry import options
- from sentry.models import GroupHash, GroupHashTombstone
- from sentry.testutils import SnubaTestCase
- from sentry.utils import snuba
- class SnubaTest(SnubaTestCase):
- def test(self):
- "This is just a simple 'hello, world' example test."
- now = datetime.now()
- events = [{
- 'event_id': 'x' * 32,
- 'primary_hash': '1' * 32,
- 'group_id': 1,
- 'project_id': self.project.id,
- 'message': 'message',
- 'platform': 'python',
- 'datetime': now.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
- 'data': {
- 'received': time.mktime(now.timetuple()),
- }
- }]
- self.snuba_insert(events)
- assert snuba.query(
- start=now - timedelta(days=1),
- end=now + timedelta(days=1),
- groupby=['project_id'],
- filter_keys={'project_id': [self.project.id]},
- ) == {self.project.id: 1}
- def test_fail(self):
- now = datetime.now()
- with pytest.raises(snuba.SnubaError):
- snuba.query(
- start=now - timedelta(days=1),
- end=now + timedelta(days=1),
- filter_keys={'project_id': [self.project.id]},
- groupby=[")("],
- )
- def test_project_issues_with_legacy_hash(self):
- a_hash = 'a' * 32
- for h in [a_hash, 'A' * 8]:
- GroupHash.objects.create(
- project=self.project,
- group=self.group,
- hash=h,
- )
- assert snuba.get_project_issues([self.project], [self.group.id]) == \
- [(self.group.id, self.group.project_id, [('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', None)])]
- # GroupHash without a group_id, should not be included in get_project_issues
- GroupHash.objects.create(
- project=self.project,
- hash='0' * 32,
- )
- group_ids = [i[0] for i in (snuba.get_project_issues([self.project]))]
- assert self.group.id in group_ids
- assert None not in group_ids
- def _insert_event_for_time(self, ts, hash='a' * 32, group_id=None):
- self.snuba_insert({
- 'event_id': uuid.uuid4().hex,
- 'primary_hash': hash,
- 'group_id': group_id if group_id else int(hash[:16], 16),
- 'project_id': self.project.id,
- 'message': 'message',
- 'platform': 'python',
- 'datetime': ts.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
- 'data': {
- 'received': time.mktime(ts.timetuple()),
- }
- })
- def test_project_issues_with_tombstones(self):
- # Nothing to be done if we're using `group_id`.
- # When this option is the default we can remove
- # this test.
- if options.get('snuba.use_group_id_column'):
- return
- base_time = datetime.utcnow()
- hash = 'a' * 32
- def _query_for_issue(group_id):
- return snuba.query(
- start=base_time - timedelta(days=1),
- end=base_time + timedelta(days=1),
- groupby=['issue'],
- filter_keys={
- 'project_id': [self.project.id],
- 'issue': [group_id]
- },
- )
- group1 = self.create_group()
- group2 = self.create_group()
- GroupHash.objects.create(
- project=self.project,
- group=group1,
- hash=hash
- )
- assert snuba.get_project_issues([self.project], [group1.id]) == \
- [(group1.id, group1.project_id, [('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', None)])]
- # 1 event in the groups, no deletes have happened
- self._insert_event_for_time(base_time, hash)
- assert _query_for_issue(group1.id) == {group1.id: 1}
- # group is deleted and then returns (as a new group with the same hash)
- GroupHashTombstone.tombstone_groups(self.project.id, [group1.id])
- ght = GroupHashTombstone.objects.get(project_id=self.project.id)
- assert ght
- GroupHash.objects.create(
- project=self.project,
- group=group2,
- hash=hash,
- )
- # tombstone time is returned as expected
- assert snuba.get_project_issues([self.project], [group2.id]) == \
- [(group2.id, group2.project_id, [('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
- ght.deleted_at.strftime("%Y-%m-%d %H:%M:%S"))])]
- # events <= to the tombstone date aren't returned
- self._insert_event_for_time(ght.deleted_at, hash)
- assert _query_for_issue(group2.id) == {}
- # only the event > than the tombstone date is returned
- self._insert_event_for_time(ght.deleted_at + timedelta(seconds=1), hash)
- assert _query_for_issue(group2.id) == {group2.id: 1}
- def test_organization_retention_respected(self):
- base_time = datetime.utcnow()
- self._insert_event_for_time(base_time - timedelta(minutes=1))
- self._insert_event_for_time(base_time - timedelta(days=2))
- def _get_event_count():
- # attempt to query back 90 days
- return snuba.query(
- start=base_time - timedelta(days=90),
- end=base_time + timedelta(days=1),
- groupby=['project_id'],
- filter_keys={
- 'project_id': [self.project.id],
- },
- )
- assert _get_event_count() == {self.project.id: 2}
- with self.options({'system.event-retention-days': 1}):
- assert _get_event_count() == {self.project.id: 1}
- def test_organization_retention_larger_than_end_date(self):
- base_time = datetime.utcnow()
- with self.options({'system.event-retention-days': 1}):
- assert snuba.query(
- start=base_time - timedelta(days=90),
- end=base_time - timedelta(days=60),
- groupby=['project_id'],
- filter_keys={
- 'project_id': [self.project.id],
- },
- ) == {}
- def test_use_group_id(self):
- base_time = datetime.utcnow()
- group = self.create_group()
- self._insert_event_for_time(base_time, group_id=group.id)
- with self.options({'snuba.use_group_id_column': True}):
- # verify filter_keys and aggregation
- assert snuba.query(
- start=base_time - timedelta(days=1),
- end=base_time + timedelta(days=1),
- groupby=['issue'],
- filter_keys={
- 'project_id': [self.project.id],
- 'issue': [group.id]
- },
- ) == {group.id: 1}
- # verify raw_query selecting issue row
- assert snuba.raw_query(
- start=base_time - timedelta(days=1),
- end=base_time + timedelta(days=1),
- selected_columns=['issue', 'timestamp'],
- filter_keys={
- 'project_id': [self.project.id],
- 'issue': [group.id]
- },
- )['data'] == [{
- 'issue': group.id,
- 'timestamp': base_time.strftime('%Y-%m-%dT%H:%M:%S+00:00'),
- }]
|