test_group_events.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. from __future__ import absolute_import
  2. import six
  3. from datetime import timedelta
  4. from django.utils import timezone
  5. from freezegun import freeze_time
  6. from sentry import options
  7. from sentry.models import Environment
  8. from sentry.testutils import APITestCase, SnubaTestCase
  9. class GroupEventsTest(APITestCase, SnubaTestCase):
  10. """
  11. This is more or less an exact copy of the tests under:
  12. /tests/sentry/api/endpoints/test_group_events.py
  13. with the removal of any explicit tagstore key/value creation calls, and
  14. comparing the resulting events by `eventID`, instead of `id`.
  15. """
  16. def setUp(self):
  17. super(GroupEventsTest, self).setUp()
  18. self.min_ago = timezone.now() - timedelta(minutes=1)
  19. options.set('snuba.events-queries.enabled', True)
  20. def test_simple(self):
  21. self.login_as(user=self.user)
  22. group = self.create_group()
  23. event_1 = self.create_event(
  24. event_id='a' * 32,
  25. datetime=self.min_ago,
  26. group=group
  27. )
  28. event_2 = self.create_event(
  29. event_id='b' * 32,
  30. datetime=self.min_ago,
  31. group=group
  32. )
  33. url = u'/api/0/issues/{}/events/'.format(group.id)
  34. response = self.client.get(url, format='json')
  35. assert response.status_code == 200, response.content
  36. assert len(response.data) == 2
  37. assert sorted(map(lambda x: x['eventID'], response.data)) == sorted(
  38. [
  39. six.text_type(event_1.event_id),
  40. six.text_type(event_2.event_id),
  41. ]
  42. )
  43. def test_tags(self):
  44. self.login_as(user=self.user)
  45. group = self.create_group()
  46. event_1 = self.create_event(
  47. event_id='a' * 32,
  48. datetime=self.min_ago,
  49. group=group,
  50. tags={
  51. 'foo': 'baz',
  52. 'bar': 'buz',
  53. }
  54. )
  55. event_2 = self.create_event(
  56. event_id='b' * 32,
  57. datetime=self.min_ago,
  58. group=group,
  59. tags={
  60. 'bar': 'biz',
  61. }
  62. )
  63. url = u'/api/0/issues/{}/events/'.format(group.id)
  64. response = self.client.get(url + '?query=foo:baz', format='json')
  65. assert response.status_code == 200, response.content
  66. assert len(response.data) == 1
  67. assert response.data[0]['eventID'] == six.text_type(event_1.event_id)
  68. response = self.client.get(url + '?query=bar:biz', format='json')
  69. assert response.status_code == 200, response.content
  70. assert len(response.data) == 1
  71. assert response.data[0]['eventID'] == six.text_type(event_2.event_id)
  72. response = self.client.get(url + '?query=bar:biz%20foo:baz', format='json')
  73. assert response.status_code == 200, response.content
  74. assert len(response.data) == 0
  75. response = self.client.get(url + '?query=bar:buz%20foo:baz', format='json')
  76. assert response.status_code == 200, response.content
  77. assert len(response.data) == 1
  78. assert response.data[0]['eventID'] == six.text_type(event_1.event_id)
  79. response = self.client.get(url + '?query=bar:baz', format='json')
  80. assert response.status_code == 200, response.content
  81. assert len(response.data) == 0
  82. response = self.client.get(url + '?query=a:b', format='json')
  83. assert response.status_code == 200, response.content
  84. assert len(response.data) == 0
  85. response = self.client.get(url + '?query=bar:b', format='json')
  86. assert response.status_code == 200, response.content
  87. assert len(response.data) == 0
  88. response = self.client.get(url + '?query=bar:baz', format='json')
  89. assert response.status_code == 200, response.content
  90. assert len(response.data) == 0
  91. def test_search_event_by_id(self):
  92. self.login_as(user=self.user)
  93. group = self.create_group()
  94. event_1 = self.create_event(
  95. event_id='a' * 32,
  96. datetime=self.min_ago,
  97. group=group
  98. )
  99. self.create_event(
  100. event_id='b' * 32,
  101. datetime=self.min_ago,
  102. group=group
  103. )
  104. url = u'/api/0/issues/{}/events/?query={}'.format(group.id, event_1.event_id)
  105. response = self.client.get(url, format='json')
  106. assert response.status_code == 200, response.content
  107. assert len(response.data) == 1
  108. assert response.data[0]['eventID'] == event_1.event_id
  109. def test_search_event_by_message(self):
  110. self.login_as(user=self.user)
  111. group = self.create_group()
  112. event_1 = self.create_event(
  113. event_id='a' * 32,
  114. datetime=self.min_ago,
  115. group=group,
  116. message="foo bar hello world"
  117. )
  118. event_2 = self.create_event(
  119. event_id='b' * 32,
  120. datetime=self.min_ago,
  121. group=group,
  122. message='this bar hello world '
  123. )
  124. query_1 = "foo"
  125. query_2 = "hello+world"
  126. # Single Word Query
  127. url = u'/api/0/issues/{}/events/?query={}'.format(group.id, query_1)
  128. response = self.client.get(url, format='json')
  129. assert response.status_code == 200, response.content
  130. assert len(response.data) == 1
  131. assert response.data[0]['eventID'] == event_1.event_id
  132. # Multiple Word Query
  133. url = u'/api/0/issues/{}/events/?query={}'.format(group.id, query_2)
  134. response = self.client.get(url, format='json')
  135. assert response.status_code == 200, response.content
  136. assert len(response.data) == 2
  137. assert sorted(map(lambda x: x['eventID'], response.data)) == sorted(
  138. [
  139. six.text_type(event_1.event_id),
  140. six.text_type(event_2.event_id),
  141. ]
  142. )
  143. def test_environment(self):
  144. self.login_as(user=self.user)
  145. group = self.create_group()
  146. events = {}
  147. for name in ['production', 'development']:
  148. Environment.get_or_create(group.project, name)
  149. events[name] = self.create_event(
  150. group=group,
  151. datetime=self.min_ago,
  152. tags={'environment': name},
  153. )
  154. url = u'/api/0/issues/{}/events/'.format(group.id)
  155. response = self.client.get(url + '?environment=production', format='json')
  156. assert response.status_code == 200, response.content
  157. assert set(map(lambda x: x['eventID'], response.data)) == set([
  158. six.text_type(events['production'].event_id),
  159. ])
  160. response = self.client.get(
  161. url,
  162. data={'environment': ['production', 'development']},
  163. format='json',
  164. )
  165. assert response.status_code == 200, response.content
  166. assert set(map(lambda x: x['eventID'], response.data)) == set([
  167. six.text_type(event.event_id)
  168. for event in events.values()
  169. ])
  170. response = self.client.get(url + '?environment=invalid', format='json')
  171. assert response.status_code == 200, response.content
  172. assert response.data == []
  173. response = self.client.get(
  174. url + '?environment=production&query=environment:development',
  175. format='json')
  176. assert response.status_code == 200, response.content
  177. assert response.data == []
  178. def test_filters_based_on_retention(self):
  179. self.login_as(user=self.user)
  180. project = self.create_project()
  181. group = self.create_group(project=project)
  182. self.create_event(
  183. event_id='a' * 32,
  184. group=group,
  185. datetime=timezone.now() - timedelta(days=2),
  186. )
  187. event_2 = self.create_event(
  188. event_id='b' * 32,
  189. datetime=self.min_ago,
  190. group=group
  191. )
  192. with self.options({'system.event-retention-days': 1}):
  193. response = self.client.get(u'/api/0/issues/{}/events/'.format(group.id))
  194. assert response.status_code == 200, response.content
  195. assert len(response.data) == 1
  196. assert sorted(map(lambda x: x['eventID'], response.data)) == sorted(
  197. [
  198. six.text_type(event_2.event_id),
  199. ]
  200. )
  201. def test_search_event_has_tags(self):
  202. self.login_as(user=self.user)
  203. group = self.create_group()
  204. self.create_event(
  205. event_id='a' * 32,
  206. datetime=self.min_ago,
  207. group=group,
  208. message="foo",
  209. tags={
  210. 'logger': 'python'
  211. }
  212. )
  213. response = self.client.get(u'/api/0/issues/{}/events/'.format(group.id))
  214. assert response.status_code == 200, response.content
  215. assert len(response.data) == 1
  216. assert response.data[0]['tags'][0] == {'key': 'logger', 'value': 'python'}
  217. @freeze_time()
  218. def test_date_filters(self):
  219. self.login_as(user=self.user)
  220. first_seen = timezone.now() - timedelta(days=5)
  221. group = self.create_group(first_seen=first_seen)
  222. event_1 = self.create_event(
  223. event_id='a' * 32,
  224. datetime=first_seen,
  225. group=group,
  226. message='foo',
  227. tags={
  228. 'logger': 'python',
  229. }
  230. )
  231. event_2 = self.create_event(
  232. event_id='b' * 32,
  233. datetime=timezone.now() - timedelta(days=1),
  234. group=group,
  235. message='bar',
  236. )
  237. response = self.client.get(
  238. u'/api/0/issues/{}/events/'.format(group.id),
  239. data={
  240. 'statsPeriod': '6d',
  241. },
  242. )
  243. assert response.status_code == 200, response.content
  244. assert len(response.data) == 2
  245. assert sorted(map(lambda x: x['eventID'], response.data)) == sorted(
  246. [
  247. six.text_type(event_1.event_id),
  248. six.text_type(event_2.event_id),
  249. ]
  250. )
  251. response = self.client.get(
  252. u'/api/0/issues/{}/events/'.format(group.id),
  253. data={
  254. 'statsPeriod': '2d',
  255. },
  256. )
  257. assert response.status_code == 200, response.content
  258. assert len(response.data) == 1
  259. assert response.data[0]['eventID'] == six.text_type(event_2.event_id)