test_organization_metrics_meta.py 10 KB

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