123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- from __future__ import absolute_import
- from datetime import datetime, timedelta
- from sentry.testutils import APITestCase
- from django.core.urlresolvers import reverse
- from sentry.testutils import SnubaTestCase
- class OrganizationDiscoverQueryTest(APITestCase, SnubaTestCase):
- def setUp(self):
- super(OrganizationDiscoverQueryTest, self).setUp()
- self.now = datetime.now()
- one_second_ago = self.now - timedelta(seconds=1)
- self.login_as(user=self.user, superuser=False)
- self.org = self.create_organization(owner=self.user, name='foo')
- self.project = self.create_project(
- name='bar',
- organization=self.org,
- )
- self.other_project = self.create_project(name='other')
- self.group = self.create_group(project=self.project, short_id=20)
- self.event = self.create_event(
- group=self.group,
- platform="python",
- datetime=one_second_ago,
- tags={'environment': 'production'},
- data={
- 'message': 'message!',
- 'exception': {
- 'values': [
- {
- 'type': 'ValidationError',
- 'value': 'Bad request',
- 'mechanism': {
- 'type': '1',
- 'value': '1',
- },
- 'stacktrace': {
- 'frames': [
- {
- 'function': '?',
- 'filename': 'http://localhost:1337/error.js',
- 'lineno': 29,
- 'colno': 3,
- 'in_app': True
- },
- ]
- },
- }
- ]
- }
- },
- )
- def test(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['message', 'platform'],
- 'start': (datetime.now() - timedelta(seconds=10)).strftime('%Y-%m-%dT%H:%M:%S'),
- 'end': (datetime.now()).strftime('%Y-%m-%dT%H:%M:%S'),
- 'orderby': '-timestamp',
- 'range': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 1
- assert response.data['data'][0]['message'] == 'message!'
- assert response.data['data'][0]['platform'] == 'python'
- def test_relative_dates(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['message', 'platform'],
- 'range': '1d',
- 'orderby': '-timestamp',
- 'start': None,
- 'end': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 1
- assert response.data['data'][0]['message'] == 'message!'
- assert response.data['data'][0]['platform'] == 'python'
- def test_invalid_date_request(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['message', 'platform'],
- 'range': '1d',
- 'start': (datetime.now() - timedelta(seconds=10)).strftime('%Y-%m-%dT%H:%M:%S'),
- 'end': (datetime.now()).strftime('%Y-%m-%dT%H:%M:%S'),
- 'orderby': '-timestamp',
- })
- assert response.status_code == 400, response.content
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['message', 'platform'],
- 'statsPeriodStart': '7d',
- 'statsPeriodEnd': '1d',
- 'start': (datetime.now() - timedelta(seconds=10)).strftime('%Y-%m-%dT%H:%M:%S'),
- 'end': (datetime.now()).strftime('%Y-%m-%dT%H:%M:%S'),
- 'orderby': '-timestamp',
- })
- assert response.status_code == 400, response.content
- def test_invalid_range_value(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['message', 'platform'],
- 'range': '1x',
- 'orderby': '-timestamp',
- 'start': None,
- 'end': None,
- })
- assert response.status_code == 400, response.content
- def test_invalid_aggregation_function(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['message', 'platform'],
- 'aggregations': [['test', 'test', 'test']],
- 'range': '14d',
- 'orderby': '-timestamp',
- 'start': None,
- 'end': None,
- })
- assert response.status_code == 400, response.content
- def test_boolean_condition(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['message', 'platform', 'stack.in_app'],
- 'conditions': [['stack.in_app', '=', True]],
- 'start': (datetime.now() - timedelta(seconds=10)).strftime('%Y-%m-%dT%H:%M:%S'),
- 'end': (datetime.now()).strftime('%Y-%m-%dT%H:%M:%S'),
- 'orderby': '-timestamp',
- 'range': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 1
- assert response.data['data'][0]['message'] == 'message!'
- assert response.data['data'][0]['platform'] == 'python'
- def test_array_join(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['message', 'error.type'],
- 'start': (datetime.now() - timedelta(seconds=10)).strftime('%Y-%m-%dT%H:%M:%S'),
- 'end': (datetime.now() + timedelta(seconds=10)).strftime('%Y-%m-%dT%H:%M:%S'),
- 'orderby': '-timestamp',
- 'range': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 1
- assert response.data['data'][0]['error.type'] == 'ValidationError'
- def test_array_condition_equals(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'conditions': [['error.type', '=', 'ValidationError']],
- 'fields': ['message'],
- 'start': (datetime.now() - timedelta(seconds=10)).strftime('%Y-%m-%dT%H:%M:%S'),
- 'end': (datetime.now()).strftime('%Y-%m-%dT%H:%M:%S'),
- 'orderby': '-timestamp',
- 'range': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 1
- def test_array_condition_not_equals(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'conditions': [['error.type', '!=', 'ValidationError']],
- 'fields': ['message'],
- 'start': (datetime.now() - timedelta(seconds=10)).strftime('%Y-%m-%dT%H:%M:%S'),
- 'end': (datetime.now()).strftime('%Y-%m-%dT%H:%M:%S'),
- 'orderby': '-timestamp',
- 'range': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 0
- def test_select_project_name(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['project.name'],
- 'range': '14d',
- 'orderby': '-timestamp',
- 'start': None,
- 'end': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 1
- assert(response.data['data'][0]['project.name']) == 'bar'
- def test_groupby_project_name(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'aggregations': [['count()', '', 'count']],
- 'fields': ['project.name'],
- 'range': '14d',
- 'orderby': '-count',
- 'start': None,
- 'end': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 1
- assert(response.data['data'][0]['project.name']) == 'bar'
- assert(response.data['data'][0]['count']) == 1
- def test_zerofilled_dates_when_rollup_relative(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'aggregations': [['count()', '', 'count']],
- 'fields': ['project.name'],
- 'groupby': ['time'],
- 'orderby': 'time',
- 'range': '5d',
- 'rollup': 86400,
- 'start': None,
- 'end': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 6
- assert(response.data['data'][5]['time']) > response.data['data'][4]['time']
- assert(response.data['data'][5]['project.name']) == 'bar'
- assert(response.data['data'][5]['count']) == 1
- def test_zerofilled_dates_when_rollup_absolute(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'aggregations': [['count()', '', 'count']],
- 'fields': ['project.name'],
- 'groupby': ['time'],
- 'orderby': '-time',
- 'start': (self.now - timedelta(seconds=300)).strftime('%Y-%m-%dT%H:%M:%S'),
- 'end': self.now.strftime('%Y-%m-%dT%H:%M:%S'),
- 'rollup': 60,
- 'range': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 6
- assert(response.data['data'][0]['time']) > response.data['data'][2]['time']
- assert(response.data['data'][0]['project.name']) == 'bar'
- assert(response.data['data'][0]['count']) == 1
- def test_uniq_project_name(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'aggregations': [['uniq', 'project.name', 'uniq_project_name']],
- 'range': '14d',
- 'orderby': '-uniq_project_name',
- 'start': None,
- 'end': None,
- })
- assert response.status_code == 200, response.content
- assert len(response.data['data']) == 1
- assert(response.data['data'][0]['uniq_project_name']) == 1
- def test_meta_types(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['project.id', 'project.name'],
- 'aggregations': [['count()', '', 'count']],
- 'range': '14d',
- 'orderby': '-count',
- 'start': None,
- 'end': None,
- })
- assert response.status_code == 200, response.content
- assert response.data['meta'] == [
- {'name': 'project.id', 'type': 'integer'},
- {'name': 'project.name', 'type': 'string'},
- {'name': 'count', 'type': 'integer'}
- ]
- def test_no_feature_access(self):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.project.id],
- 'fields': ['message', 'platform'],
- 'range': '14d',
- 'orderby': '-timestamp',
- 'start': None,
- 'end': None,
- })
- assert response.status_code == 404, response.content
- def test_invalid_project(self):
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.org.slug])
- response = self.client.post(url, {
- 'projects': [self.other_project.id],
- 'fields': ['message', 'platform'],
- 'range': '14d',
- 'orderby': '-timestamp',
- 'start': None,
- 'end': None,
- })
- assert response.status_code == 403, response.content
- def test_superuser(self):
- self.new_org = self.create_organization(name='foo_new')
- self.new_project = self.create_project(
- name='bar_new',
- organization=self.new_org,
- )
- self.login_as(user=self.user, superuser=True)
- with self.feature('organizations:discover'):
- url = reverse('sentry-api-0-organization-discover-query', args=[self.new_org.slug])
- response = self.client.post(url, {
- 'projects': [self.new_project.id],
- 'fields': ['message', 'platform'],
- 'start': (datetime.now() - timedelta(seconds=10)).strftime('%Y-%m-%dT%H:%M:%S'),
- 'end': (datetime.now()).strftime('%Y-%m-%dT%H:%M:%S'),
- 'orderby': '-timestamp',
- 'range': None,
- })
- assert response.status_code == 200, response.content
|