test_organization_group_index_stats.py 8.1 KB

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