test_organization_group_index_stats.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import uuid
  2. from sentry.issues.grouptype import ProfileFileIOGroupType
  3. from sentry.testutils.cases import APITestCase, SnubaTestCase
  4. from sentry.testutils.helpers.datetime import before_now
  5. from tests.sentry.issues.test_utils import OccurrenceTestMixin
  6. class GroupListTest(APITestCase, SnubaTestCase, OccurrenceTestMixin):
  7. endpoint = "sentry-api-0-organization-group-index-stats"
  8. def setUp(self):
  9. super().setUp()
  10. self.min_ago = before_now(minutes=1)
  11. def get_response(self, *args, **kwargs):
  12. return super().get_response(self.project.organization.slug, **kwargs)
  13. def test_simple(self):
  14. self.store_event(
  15. data={"timestamp": before_now(seconds=500).isoformat(), "fingerprint": ["group-1"]},
  16. project_id=self.project.id,
  17. )
  18. group_a = self.store_event(
  19. data={"timestamp": before_now(seconds=1).isoformat(), "fingerprint": ["group-a"]},
  20. project_id=self.project.id,
  21. ).group
  22. self.store_event(
  23. data={"timestamp": before_now(seconds=2).isoformat(), "fingerprint": ["group-b"]},
  24. project_id=self.project.id,
  25. )
  26. group_c = self.store_event(
  27. data={"timestamp": before_now(seconds=3).isoformat(), "fingerprint": ["group-c"]},
  28. project_id=self.project.id,
  29. ).group
  30. self.login_as(user=self.user)
  31. response = self.get_response(query="is:unresolved", groups=[group_a.id, group_c.id])
  32. response_data = sorted(response.data, key=lambda x: x["firstSeen"], reverse=True)
  33. assert response.status_code == 200
  34. assert len(response_data) == 2
  35. assert int(response_data[0]["id"]) == group_a.id
  36. assert int(response_data[1]["id"]) == group_c.id
  37. assert "title" not in response_data[0]
  38. assert "hasSeen" not in response_data[0]
  39. assert "stats" in response_data[0]
  40. assert "firstSeen" in response_data[0]
  41. assert "lastSeen" in response_data[0]
  42. assert "count" in response_data[0]
  43. assert "userCount" in response_data[0]
  44. assert "lifetime" in response_data[0]
  45. assert "filtered" in response_data[0]
  46. def test_unhandled(self):
  47. self.store_event(
  48. data={"timestamp": before_now(seconds=500).isoformat(), "fingerprint": ["group-1"]},
  49. project_id=self.project.id,
  50. )
  51. group_a = self.store_event(
  52. data={"timestamp": before_now(seconds=1).isoformat(), "fingerprint": ["group-a"]},
  53. project_id=self.project.id,
  54. ).group
  55. self.login_as(user=self.user)
  56. response = self.get_response(query="is:unresolved", groups=[group_a.id])
  57. response_data = sorted(response.data, key=lambda x: x["firstSeen"], reverse=True)
  58. assert response.status_code == 200
  59. assert len(response_data) == 1
  60. assert "title" not in response_data[0]
  61. assert "hasSeen" not in response_data[0]
  62. assert "stats" in response_data[0]
  63. assert "firstSeen" in response_data[0]
  64. assert "lastSeen" in response_data[0]
  65. assert "count" in response_data[0]
  66. assert "userCount" in response_data[0]
  67. assert "lifetime" in response_data[0]
  68. assert "filtered" in response_data[0]
  69. assert "isUnhandled" in response_data[0]
  70. def test_issue_platform_issue(self):
  71. event_id = uuid.uuid4().hex
  72. _, group_info = self.process_occurrence(
  73. event_id=event_id,
  74. project_id=self.project.id,
  75. type=ProfileFileIOGroupType.type_id,
  76. event_data={
  77. "fingerprint": ["group-1"],
  78. "timestamp": before_now(minutes=1).isoformat(),
  79. },
  80. )
  81. assert group_info is not None
  82. profile_group = group_info.group
  83. self.login_as(user=self.user)
  84. response = self.get_response(
  85. query=f"issue:{profile_group.qualified_short_id}", groups=[profile_group.id]
  86. )
  87. response_data = sorted(response.data, key=lambda x: x["firstSeen"], reverse=True)
  88. assert response.status_code == 200
  89. assert len(response_data) == 1
  90. assert int(response_data[0]["id"]) == profile_group.id
  91. assert "title" not in response_data[0]
  92. assert "hasSeen" not in response_data[0]
  93. assert "stats" in response_data[0]
  94. assert "firstSeen" in response_data[0]
  95. assert "lastSeen" in response_data[0]
  96. assert "count" in response_data[0]
  97. assert "userCount" in response_data[0]
  98. assert "lifetime" in response_data[0]
  99. assert "filtered" in response_data[0]
  100. def test_issue_platform_mixed_issue_not_title(self):
  101. event_id = uuid.uuid4().hex
  102. _, group_info = self.process_occurrence(
  103. event_id=event_id,
  104. project_id=self.project.id,
  105. type=ProfileFileIOGroupType.type_id,
  106. event_data={
  107. "fingerprint": ["group-a"],
  108. "timestamp": before_now(minutes=1).isoformat(),
  109. },
  110. )
  111. assert group_info is not None
  112. profile_group = group_info.group
  113. error_event = self.store_event(
  114. data={"timestamp": before_now(seconds=500).isoformat(), "fingerprint": ["group-1"]},
  115. project_id=self.project.id,
  116. )
  117. error_group = error_event.group
  118. self.login_as(user=self.user)
  119. response = self.get_response(
  120. query=f"!title:{profile_group.title}", groups=[profile_group.id, error_group.id]
  121. )
  122. response_data = sorted(response.data, key=lambda x: x["firstSeen"], reverse=True)
  123. assert response.status_code == 200
  124. assert [int(grp["id"]) for grp in response_data] == [profile_group.id, error_group.id]
  125. for data in response_data:
  126. assert "title" not in data
  127. assert "hasSeen" not in data
  128. assert "stats" in data
  129. assert "firstSeen" in data
  130. assert "lastSeen" in data
  131. assert "count" in data
  132. assert "userCount" in data
  133. assert "lifetime" in data
  134. assert "filtered" in data
  135. def test_no_matching_groups(self):
  136. self.login_as(user=self.user)
  137. response = self.get_response(sort_by="date", limit=10, query="is:unresolved", groups=[1337])
  138. assert response.status_code == 400
  139. def test_simple_with_project(self):
  140. self.store_event(
  141. data={"timestamp": before_now(seconds=500).isoformat(), "fingerprint": ["group-1"]},
  142. project_id=self.project.id,
  143. )
  144. group_a = self.store_event(
  145. data={"timestamp": before_now(seconds=1).isoformat(), "fingerprint": ["group-a"]},
  146. project_id=self.project.id,
  147. ).group
  148. self.store_event(
  149. data={"timestamp": before_now(seconds=2).isoformat(), "fingerprint": ["group-b"]},
  150. project_id=self.project.id,
  151. )
  152. group_c = self.store_event(
  153. data={"timestamp": before_now(seconds=3).isoformat(), "fingerprint": ["group-c"]},
  154. project_id=self.project.id,
  155. ).group
  156. self.login_as(user=self.user)
  157. response = self.get_response(
  158. query=f"project:{self.project.slug}", groups=[group_a.id, group_c.id]
  159. )
  160. assert response.status_code == 200
  161. assert len(response.data) == 2
  162. def test_query_timestamp(self):
  163. self.store_event(
  164. data={"timestamp": before_now(seconds=500).isoformat(), "fingerprint": ["group-1"]},
  165. project_id=self.project.id,
  166. )
  167. event2 = self.store_event(
  168. data={"timestamp": before_now(seconds=1).isoformat(), "fingerprint": ["group-a"]},
  169. project_id=self.project.id,
  170. )
  171. self.store_event(
  172. data={"timestamp": before_now(seconds=2).isoformat(), "fingerprint": ["group-b"]},
  173. project_id=self.project.id,
  174. )
  175. event4 = self.store_event(
  176. data={"timestamp": before_now(seconds=3).isoformat(), "fingerprint": ["group-c"]},
  177. project_id=self.project.id,
  178. )
  179. group_a = event2.group
  180. group_c = event4.group
  181. self.login_as(user=self.user)
  182. response = self.get_response(
  183. query=f"timestamp:>{before_now(seconds=3)} timestamp:<{before_now(seconds=1).isoformat()}",
  184. groups=[group_a.id, group_c.id],
  185. )
  186. assert response.status_code == 200
  187. assert len(response.data) == 2