test_integration.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. from io import BytesIO
  2. from uuid import uuid4
  3. import pytest
  4. from sentry.models.eventattachment import EventAttachment
  5. from sentry.spans.grouping.utils import hash_values
  6. from sentry.testutils import RelayStoreHelper, TransactionTestCase
  7. from sentry.testutils.helpers import Feature
  8. from sentry.testutils.helpers.datetime import before_now, iso_format, timestamp_format
  9. class SentryRemoteTest(RelayStoreHelper, TransactionTestCase):
  10. # used to be test_ungzipped_data
  11. def test_simple_data(self):
  12. event_data = {"message": "hello", "timestamp": iso_format(before_now(seconds=1))}
  13. event = self.post_and_retrieve_event(event_data)
  14. assert event.message == "hello"
  15. def test_csp(self):
  16. event_data = {
  17. "csp-report": {
  18. "document-uri": "https://example.com/foo/bar",
  19. "referrer": "https://www.google.com/",
  20. "violated-directive": "default-src self",
  21. "original-policy": "default-src self; report-uri /csp-hotline.php",
  22. "blocked-uri": "http://evilhackerscripts.com",
  23. }
  24. }
  25. event = self.post_and_retrieve_security_report(event_data)
  26. assert event.message == "Blocked 'default-src' from 'evilhackerscripts.com'"
  27. def test_hpkp(self):
  28. event_data = {
  29. "date-time": "2014-04-06T13:00:50Z",
  30. "hostname": "www.example.com",
  31. "port": 443,
  32. "effective-expiration-date": "2014-05-01T12:40:50Z",
  33. "include-subdomains": False,
  34. "served-certificate-chain": [
  35. "-----BEGIN CERTIFICATE-----\n MIIEBDCCAuygBQUAMEIxCzAJBgNVBAYTAlVT\n -----END CERTIFICATE-----"
  36. ],
  37. "validated-certificate-chain": [
  38. "-----BEGIN CERTIFICATE-----\n MIIEBDCCAuygAwIBAgIDCzAJBgNVBAYTAlVT\n -----END CERTIFICATE-----"
  39. ],
  40. "known-pins": [
  41. 'pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="',
  42. 'pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="',
  43. ],
  44. }
  45. event = self.post_and_retrieve_security_report(event_data)
  46. assert event.message == "Public key pinning validation failed for 'www.example.com'"
  47. assert event.group.title == "Public key pinning validation failed for 'www.example.com'"
  48. def test_expect_ct(self):
  49. event_data = {
  50. "expect-ct-report": {
  51. "date-time": "2014-04-06T13:00:50Z",
  52. "hostname": "www.example.com",
  53. "port": 443,
  54. "effective-expiration-date": "2014-05-01T12:40:50Z",
  55. "served-certificate-chain": [
  56. "-----BEGIN CERTIFICATE-----\nABC\n-----END CERTIFICATE-----"
  57. ],
  58. "validated-certificate-chain": [
  59. "-----BEGIN CERTIFICATE-----\nCDE\n-----END CERTIFICATE-----"
  60. ],
  61. "scts": [
  62. {
  63. "version": 1,
  64. "status": "invalid",
  65. "source": "embedded",
  66. "serialized_sct": "ABCD==",
  67. }
  68. ],
  69. }
  70. }
  71. event = self.post_and_retrieve_security_report(event_data)
  72. assert event.message == "Expect-CT failed for 'www.example.com'"
  73. assert event.group.title == "Expect-CT failed for 'www.example.com'"
  74. def test_expect_staple(self):
  75. event_data = {
  76. "expect-staple-report": {
  77. "date-time": "2014-04-06T13:00:50Z",
  78. "hostname": "www.example.com",
  79. "port": 443,
  80. "response-status": "ERROR_RESPONSE",
  81. "cert-status": "REVOKED",
  82. "effective-expiration-date": "2014-05-01T12:40:50Z",
  83. "served-certificate-chain": [
  84. "-----BEGIN CERTIFICATE-----\nABC\n-----END CERTIFICATE-----"
  85. ],
  86. "validated-certificate-chain": [
  87. "-----BEGIN CERTIFICATE-----\nCDE\n-----END CERTIFICATE-----"
  88. ],
  89. }
  90. }
  91. event = self.post_and_retrieve_security_report(event_data)
  92. assert event.message == "Expect-Staple failed for 'www.example.com'"
  93. assert event.group.title == "Expect-Staple failed for 'www.example.com'"
  94. def test_standalone_attachment(self):
  95. event_id = uuid4().hex
  96. # First, ingest the attachment and ensure it is saved
  97. files = {"some_file": ("hello.txt", BytesIO(b"Hello World!"))}
  98. self.post_and_retrieve_attachment(event_id, files)
  99. # Next, ingest an error event
  100. event = self.post_and_retrieve_event({"event_id": event_id, "message": "my error"})
  101. assert event.event_id == event_id
  102. assert event.group_id
  103. # Finally, fetch the updated attachment and compare the group id
  104. attachment = EventAttachment.objects.get(project_id=self.project.id, event_id=event_id)
  105. assert attachment.group_id == event.group_id
  106. def test_transaction(self):
  107. event_data = {
  108. "event_id": "d2132d31b39445f1938d7e21b6bf0ec4",
  109. "type": "transaction",
  110. "transaction": "/organizations/:orgId/performance/:eventSlug/",
  111. "start_timestamp": iso_format(before_now(minutes=1, milliseconds=500)),
  112. "timestamp": iso_format(before_now(minutes=1)),
  113. "contexts": {
  114. "trace": {
  115. "trace_id": "ff62a8b040f340bda5d830223def1d81",
  116. "span_id": "8f5a2b8768cafb4e",
  117. "type": "trace",
  118. }
  119. },
  120. "spans": [
  121. {
  122. "description": "<OrganizationContext>",
  123. "op": "react.mount",
  124. "parent_span_id": "8f5a2b8768cafb4e",
  125. "span_id": "bd429c44b67a3eb4",
  126. "start_timestamp": timestamp_format(before_now(minutes=1, milliseconds=250)),
  127. "timestamp": timestamp_format(before_now(minutes=1)),
  128. "trace_id": "ff62a8b040f340bda5d830223def1d81",
  129. },
  130. {
  131. "description": "browser span",
  132. "op": "browser",
  133. "parent_span_id": "bd429c44b67a3eb4",
  134. "span_id": "a99fd04e79e17631",
  135. "start_timestamp": timestamp_format(before_now(minutes=1, milliseconds=200)),
  136. "timestamp": timestamp_format(before_now(minutes=1)),
  137. "trace_id": "ff62a8b040f340bda5d830223def1d81",
  138. },
  139. {
  140. "description": "resource span",
  141. "op": "resource",
  142. "parent_span_id": "bd429c44b67a3eb4",
  143. "span_id": "a71a5e67db5ce938",
  144. "start_timestamp": timestamp_format(before_now(minutes=1, milliseconds=200)),
  145. "timestamp": timestamp_format(before_now(minutes=1)),
  146. "trace_id": "ff62a8b040f340bda5d830223def1d81",
  147. },
  148. {
  149. "description": "http span",
  150. "op": "http",
  151. "parent_span_id": "a99fd04e79e17631",
  152. "span_id": "abe79ad9292b90a9",
  153. "start_timestamp": timestamp_format(before_now(minutes=1, milliseconds=200)),
  154. "timestamp": timestamp_format(before_now(minutes=1)),
  155. "trace_id": "ff62a8b040f340bda5d830223def1d81",
  156. },
  157. {
  158. "description": "db span",
  159. "op": "db",
  160. "parent_span_id": "abe79ad9292b90a9",
  161. "span_id": "9c045ea336297177",
  162. "start_timestamp": timestamp_format(before_now(minutes=1, milliseconds=200)),
  163. "timestamp": timestamp_format(before_now(minutes=1)),
  164. "trace_id": "ff62a8b040f340bda5d830223def1d81",
  165. },
  166. ],
  167. }
  168. with Feature(
  169. {
  170. "organizations:performance-ops-breakdown": True,
  171. "projects:performance-suspect-spans-ingestion": True,
  172. }
  173. ):
  174. event = self.post_and_retrieve_event(event_data)
  175. raw_event = event.get_raw_data()
  176. exclusive_times = [
  177. pytest.approx(50, rel=1e3),
  178. pytest.approx(0, rel=1e3),
  179. pytest.approx(200, rel=1e3),
  180. pytest.approx(0, rel=1e3),
  181. pytest.approx(200, rel=1e3),
  182. ]
  183. for actual, expected, exclusive_time in zip(
  184. raw_event["spans"], event_data["spans"], exclusive_times
  185. ):
  186. assert actual == dict(
  187. expected,
  188. exclusive_time=exclusive_time,
  189. hash=hash_values([expected["description"]]),
  190. )
  191. assert raw_event["breakdowns"] == {
  192. "span_ops": {
  193. "ops.browser": {"unit": "millisecond", "value": pytest.approx(200, rel=1e3)},
  194. "ops.resource": {"unit": "millisecond", "value": pytest.approx(200, rel=1e3)},
  195. "ops.http": {"unit": "millisecond", "value": pytest.approx(200, rel=1e3)},
  196. "ops.db": {"unit": "millisecond", "value": pytest.approx(200, rel=1e3)},
  197. "total.time": {"unit": "millisecond", "value": pytest.approx(1050, rel=1e3)},
  198. }
  199. }