test_organization_events_span_indexed.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. from tests.snuba.api.endpoints.test_organization_events import OrganizationEventsEndpointTestBase
  2. class OrganizationEventsSpanIndexedEndpointTest(OrganizationEventsEndpointTestBase):
  3. """Test the indexed spans dataset.
  4. To run this locally you may need to set the ENABLE_SPANS_CONSUMER flag to True in Snuba.
  5. A way to do this is
  6. 1. run: `sentry devservices down snuba`
  7. 2. clone snuba locally
  8. 3. run: `export ENABLE_SPANS_CONSUMER=True`
  9. 4. run snuba
  10. At this point tests should work locally
  11. Once span ingestion is on by default this will no longer need to be done
  12. """
  13. def setUp(self):
  14. super().setUp()
  15. self.features = {
  16. "organizations:starfish-view": True,
  17. }
  18. def test_simple(self):
  19. self.store_spans(
  20. [
  21. self.create_span({"description": "foo"}, start_ts=self.ten_mins_ago),
  22. self.create_span({"description": "bar"}, start_ts=self.ten_mins_ago),
  23. ]
  24. )
  25. response = self.do_request(
  26. {
  27. "field": ["description", "count()"],
  28. "query": "",
  29. "orderby": "description",
  30. "project": self.project.id,
  31. "dataset": "spansIndexed",
  32. }
  33. )
  34. assert response.status_code == 200, response.content
  35. data = response.data["data"]
  36. meta = response.data["meta"]
  37. assert len(data) == 2
  38. assert data[0]["description"] == "bar"
  39. assert data[1]["description"] == "foo"
  40. assert meta["dataset"] == "spansIndexed"
  41. def test_sentry_tags_vs_tags(self):
  42. self.store_spans(
  43. [
  44. self.create_span(
  45. {"sentry_tags": {"transaction.method": "foo"}}, start_ts=self.ten_mins_ago
  46. ),
  47. ]
  48. )
  49. response = self.do_request(
  50. {
  51. "field": ["transaction.method", "count()"],
  52. "query": "",
  53. "orderby": "count()",
  54. "project": self.project.id,
  55. "dataset": "spansIndexed",
  56. }
  57. )
  58. assert response.status_code == 200, response.content
  59. data = response.data["data"]
  60. meta = response.data["meta"]
  61. assert len(data) == 1
  62. assert data[0]["transaction.method"] == "foo"
  63. assert meta["dataset"] == "spansIndexed"
  64. def test_sentry_tags_syntax(self):
  65. self.store_spans(
  66. [
  67. self.create_span(
  68. {"sentry_tags": {"transaction.method": "foo"}}, start_ts=self.ten_mins_ago
  69. ),
  70. ]
  71. )
  72. response = self.do_request(
  73. {
  74. "field": ["sentry_tags[transaction.method]", "count()"],
  75. "query": "",
  76. "orderby": "count()",
  77. "project": self.project.id,
  78. "dataset": "spansIndexed",
  79. }
  80. )
  81. assert response.status_code == 200, response.content
  82. data = response.data["data"]
  83. meta = response.data["meta"]
  84. assert len(data) == 1
  85. assert data[0]["sentry_tags[transaction.method]"] == "foo"
  86. assert meta["dataset"] == "spansIndexed"
  87. def test_device_class_filter_unknown(self):
  88. self.store_spans(
  89. [
  90. self.create_span({"sentry_tags": {"device.class": ""}}, start_ts=self.ten_mins_ago),
  91. ]
  92. )
  93. response = self.do_request(
  94. {
  95. "field": ["device.class", "count()"],
  96. "query": "device.class:Unknown",
  97. "orderby": "count()",
  98. "project": self.project.id,
  99. "dataset": "spansIndexed",
  100. }
  101. )
  102. assert response.status_code == 200, response.content
  103. data = response.data["data"]
  104. meta = response.data["meta"]
  105. assert len(data) == 1
  106. assert data[0]["device.class"] == "Unknown"
  107. assert meta["dataset"] == "spansIndexed"
  108. def test_network_span(self):
  109. self.store_spans(
  110. [
  111. self.create_span(
  112. {
  113. "sentry_tags": {
  114. "action": "GET",
  115. "category": "http",
  116. "description": "GET https://*.resource.com",
  117. "domain": "*.resource.com",
  118. "op": "http.client",
  119. "status_code": "200",
  120. "transaction": "/api/0/data/",
  121. "transaction.method": "GET",
  122. "transaction.op": "http.server",
  123. }
  124. },
  125. start_ts=self.ten_mins_ago,
  126. ),
  127. ]
  128. )
  129. response = self.do_request(
  130. {
  131. "field": ["span.op", "span.status_code"],
  132. "query": "span.status_code:200",
  133. "project": self.project.id,
  134. "dataset": "spansIndexed",
  135. }
  136. )
  137. assert response.status_code == 200, response.content
  138. data = response.data["data"]
  139. meta = response.data["meta"]
  140. assert len(data) == 1
  141. assert data[0]["span.op"] == "http.client"
  142. assert data[0]["span.status_code"] == "200"
  143. assert meta["dataset"] == "spansIndexed"
  144. def test_inp_span(self):
  145. self.store_spans(
  146. [
  147. self.create_span(
  148. {
  149. "sentry_tags": {
  150. "replay_id": "abc123",
  151. "browser.name": "Chrome",
  152. "transaction": "/pageloads/",
  153. }
  154. },
  155. start_ts=self.ten_mins_ago,
  156. ),
  157. ]
  158. )
  159. response = self.do_request(
  160. {
  161. "field": ["replay.id", "browser.name", "origin.transaction", "count()"],
  162. "query": "replay.id:abc123 AND browser.name:Chrome AND origin.transaction:/pageloads/",
  163. "orderby": "count()",
  164. "project": self.project.id,
  165. "dataset": "spansIndexed",
  166. }
  167. )
  168. assert response.status_code == 200, response.content
  169. data = response.data["data"]
  170. meta = response.data["meta"]
  171. assert len(data) == 1
  172. assert data[0]["replay.id"] == "abc123"
  173. assert data[0]["browser.name"] == "Chrome"
  174. assert data[0]["origin.transaction"] == "/pageloads/"
  175. assert meta["dataset"] == "spansIndexed"