test_organization_metrics_meta.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. import pytest
  2. from django.urls import reverse
  3. from sentry.testutils.cases import MetricsEnhancedPerformanceTestCase
  4. from sentry.testutils.helpers.datetime import before_now, iso_format
  5. pytestmark = pytest.mark.sentry_metrics
  6. class OrganizationMetricsCompatiblity(MetricsEnhancedPerformanceTestCase):
  7. def setUp(self):
  8. super().setUp()
  9. self.min_ago = before_now(minutes=1)
  10. self.two_min_ago = before_now(minutes=2)
  11. self.features = {
  12. "organizations:performance-use-metrics": True,
  13. }
  14. self.login_as(user=self.user)
  15. # Don't create any txn on this, don't set its DS rules, it shouldn't show up anywhere
  16. self.bad_project = self.create_project()
  17. def test_unparameterized_transactions(self):
  18. # Make current project incompatible
  19. self.store_transaction_metric(
  20. 1, tags={"transaction": "<< unparameterized >>"}, timestamp=self.min_ago
  21. )
  22. url = reverse(
  23. "sentry-api-0-organization-metrics-compatibility",
  24. kwargs={"organization_id_or_slug": self.project.organization.slug},
  25. )
  26. response = self.client.get(url, format="json")
  27. assert response.status_code == 200, response.content
  28. self.assertCountEqual(
  29. response.json()["incompatible_projects"], [self.project.id, self.bad_project.id]
  30. )
  31. assert response.json()["compatible_projects"] == []
  32. def test_null_transaction(self):
  33. # Make current project incompatible
  34. self.store_transaction_metric(1, tags={}, timestamp=self.min_ago)
  35. url = reverse(
  36. "sentry-api-0-organization-metrics-compatibility",
  37. kwargs={"organization_id_or_slug": self.project.organization.slug},
  38. )
  39. response = self.client.get(url, format="json")
  40. assert response.status_code == 200, response.content
  41. self.assertCountEqual(
  42. response.json()["incompatible_projects"], [self.project.id, self.bad_project.id]
  43. )
  44. assert response.json()["compatible_projects"] == []
  45. def test_no_transaction(self):
  46. # Make current project incompatible by having nothing
  47. url = reverse(
  48. "sentry-api-0-organization-metrics-compatibility",
  49. kwargs={"organization_id_or_slug": self.project.organization.slug},
  50. )
  51. response = self.client.get(url, format="json")
  52. assert response.status_code == 200, response.content
  53. self.assertCountEqual(
  54. response.json()["incompatible_projects"], [self.project.id, self.bad_project.id]
  55. )
  56. assert response.json()["compatible_projects"] == []
  57. def test_has_transaction(self):
  58. self.store_transaction_metric(
  59. 1, tags={"transaction": "foo_transaction"}, timestamp=self.min_ago
  60. )
  61. url = reverse(
  62. "sentry-api-0-organization-metrics-compatibility",
  63. kwargs={"organization_id_or_slug": self.project.organization.slug},
  64. )
  65. response = self.client.get(url, format="json")
  66. assert response.status_code == 200, response.content
  67. assert response.json()["incompatible_projects"] == [self.bad_project.id]
  68. assert response.json()["compatible_projects"] == [self.project.id]
  69. def test_multiple_projects(self):
  70. project2 = self.create_project()
  71. project3 = self.create_project()
  72. project4 = self.create_project()
  73. self.store_transaction_metric(
  74. 1, tags={"transaction": "foo_transaction"}, timestamp=self.min_ago
  75. )
  76. self.store_transaction_metric(
  77. 1, tags={"transaction": "foo_transaction"}, timestamp=self.min_ago, project=project4.id
  78. )
  79. self.store_transaction_metric(
  80. 1,
  81. tags={"transaction": "<< unparameterized >>"},
  82. timestamp=self.min_ago,
  83. project=project2.id,
  84. )
  85. self.store_transaction_metric(
  86. 1,
  87. tags={},
  88. timestamp=self.min_ago,
  89. project=project3.id,
  90. )
  91. self.store_event(
  92. data={"timestamp": iso_format(self.min_ago), "transaction": "foo_transaction"},
  93. project_id=self.project.id,
  94. )
  95. url = reverse(
  96. "sentry-api-0-organization-metrics-compatibility",
  97. kwargs={"organization_id_or_slug": self.project.organization.slug},
  98. )
  99. response = self.client.get(url, format="json")
  100. assert response.status_code == 200, response.content
  101. self.assertCountEqual(
  102. response.json()["incompatible_projects"],
  103. [project2.id, project3.id, self.bad_project.id],
  104. )
  105. self.assertCountEqual(
  106. response.json()["compatible_projects"], [self.project.id, project4.id]
  107. )
  108. class OrganizationEventsMetricsSums(MetricsEnhancedPerformanceTestCase):
  109. def setUp(self):
  110. super().setUp()
  111. self.min_ago = before_now(minutes=1)
  112. self.two_min_ago = before_now(minutes=2)
  113. self.features = {
  114. "organizations:performance-use-metrics": True,
  115. }
  116. self.login_as(user=self.user)
  117. # Don't create any txn on this, don't set its DS rules, it shouldn't show up anywhere
  118. self.create_project()
  119. def test_unparameterized_transactions(self):
  120. # Make current project incompatible
  121. self.store_transaction_metric(
  122. 1, tags={"transaction": "<< unparameterized >>"}, timestamp=self.min_ago
  123. )
  124. url = reverse(
  125. "sentry-api-0-organization-metrics-compatibility-sums",
  126. kwargs={"organization_id_or_slug": self.project.organization.slug},
  127. )
  128. response = self.client.get(url, format="json")
  129. assert response.status_code == 200, response.content
  130. assert response.json()["sum"]["metrics"] == 1
  131. assert response.json()["sum"]["metrics_unparam"] == 1
  132. assert response.json()["sum"]["metrics_null"] == 0
  133. def test_null_transaction(self):
  134. # Make current project incompatible
  135. self.store_transaction_metric(1, tags={}, timestamp=self.min_ago)
  136. url = reverse(
  137. "sentry-api-0-organization-metrics-compatibility-sums",
  138. kwargs={"organization_id_or_slug": self.project.organization.slug},
  139. )
  140. response = self.client.get(url, format="json")
  141. assert response.status_code == 200, response.content
  142. assert response.json()["sum"]["metrics"] == 1
  143. assert response.json()["sum"]["metrics_unparam"] == 0
  144. assert response.json()["sum"]["metrics_null"] == 1
  145. def test_no_transaction(self):
  146. # Make current project incompatible by having nothing
  147. url = reverse(
  148. "sentry-api-0-organization-metrics-compatibility-sums",
  149. kwargs={"organization_id_or_slug": self.project.organization.slug},
  150. )
  151. response = self.client.get(url, format="json")
  152. assert response.status_code == 200, response.content
  153. assert response.json()["sum"]["metrics"] == 0
  154. assert response.json()["sum"]["metrics_unparam"] == 0
  155. assert response.json()["sum"]["metrics_null"] == 0
  156. def test_has_transaction(self):
  157. self.store_transaction_metric(
  158. 1, tags={"transaction": "foo_transaction"}, timestamp=self.min_ago
  159. )
  160. url = reverse(
  161. "sentry-api-0-organization-metrics-compatibility-sums",
  162. kwargs={"organization_id_or_slug": self.project.organization.slug},
  163. )
  164. response = self.client.get(url, format="json")
  165. assert response.status_code == 200, response.content
  166. assert response.json()["sum"]["metrics"] == 1
  167. assert response.json()["sum"]["metrics_unparam"] == 0
  168. assert response.json()["sum"]["metrics_null"] == 0
  169. def test_multiple_projects(self):
  170. project2 = self.create_project()
  171. project3 = self.create_project()
  172. # Not setting DS, it shouldn't show up
  173. project4 = self.create_project()
  174. self.store_transaction_metric(
  175. 1, tags={"transaction": "foo_transaction"}, timestamp=self.min_ago
  176. )
  177. self.store_transaction_metric(
  178. 1, tags={"transaction": "foo_transaction"}, timestamp=self.min_ago, project=project4.id
  179. )
  180. self.store_transaction_metric(
  181. 1,
  182. tags={"transaction": "<< unparameterized >>"},
  183. timestamp=self.min_ago,
  184. project=project2.id,
  185. )
  186. self.store_transaction_metric(
  187. 1,
  188. tags={},
  189. timestamp=self.min_ago,
  190. project=project3.id,
  191. )
  192. self.store_event(
  193. data={"timestamp": iso_format(self.min_ago), "transaction": "foo_transaction"},
  194. project_id=self.project.id,
  195. )
  196. url = reverse(
  197. "sentry-api-0-organization-metrics-compatibility-sums",
  198. kwargs={"organization_id_or_slug": self.project.organization.slug},
  199. )
  200. response = self.client.get(url, format="json")
  201. assert response.status_code == 200, response.content
  202. assert response.json()["sum"]["metrics"] == 4
  203. assert response.json()["sum"]["metrics_unparam"] == 1
  204. assert response.json()["sum"]["metrics_null"] == 1
  205. def test_counts_add_up_correctly(self):
  206. # Make current project incompatible
  207. for _ in range(2):
  208. self.store_transaction_metric(
  209. 1, tags={"transaction": "<< unparameterized >>"}, timestamp=self.min_ago
  210. )
  211. for _ in range(3):
  212. self.store_transaction_metric(1, tags={}, timestamp=self.min_ago)
  213. for _ in range(1):
  214. self.store_transaction_metric(1, tags={"transaction": "/foo"}, timestamp=self.min_ago)
  215. url = reverse(
  216. "sentry-api-0-organization-metrics-compatibility-sums",
  217. kwargs={"organization_id_or_slug": self.project.organization.slug},
  218. )
  219. response = self.client.get(url, format="json")
  220. assert response.status_code == 200, response.content
  221. assert response.json()["sum"]["metrics"] == 6
  222. assert response.json()["sum"]["metrics_unparam"] == 2
  223. assert response.json()["sum"]["metrics_null"] == 3