test_unreal_full.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. from __future__ import absolute_import
  2. import pytest
  3. import zipfile
  4. from sentry.utils.compat.mock import patch
  5. from six import BytesIO
  6. from django.core.urlresolvers import reverse
  7. from django.core.files.uploadedfile import SimpleUploadedFile
  8. from django.test import override_settings
  9. from sentry.testutils import TransactionTestCase
  10. from sentry.models import EventAttachment
  11. from sentry import eventstore
  12. from sentry.lang.native.utils import STORE_CRASH_REPORTS_ALL
  13. from tests.symbolicator import get_fixture_path
  14. # IMPORTANT:
  15. # For these tests to run, write `symbolicator.enabled: true` into your
  16. # `~/.sentry/config.yml` and run `sentry devservices up`
  17. def get_unreal_crash_file():
  18. return get_fixture_path("unreal_crash")
  19. def get_unreal_crash_apple_file():
  20. return get_fixture_path("unreal_crash_apple")
  21. @override_settings(ALLOWED_HOSTS=["localhost", "testserver", "host.docker.internal"])
  22. class SymbolicatorUnrealIntegrationTest(TransactionTestCase):
  23. # For these tests to run, write `symbolicator.enabled: true` into your
  24. # `~/.sentry/config.yml` and run `sentry devservices up`
  25. @pytest.fixture(autouse=True)
  26. def initialize(self, live_server):
  27. self.project.update_option("sentry:builtin_symbol_sources", [])
  28. new_prefix = live_server.url
  29. with patch("sentry.auth.system.is_internal_ip", return_value=True), self.options(
  30. {"system.url-prefix": new_prefix}
  31. ):
  32. # Run test case:
  33. yield
  34. def upload_symbols(self):
  35. url = reverse(
  36. "sentry-api-0-dsym-files",
  37. kwargs={
  38. "organization_slug": self.project.organization.slug,
  39. "project_slug": self.project.slug,
  40. },
  41. )
  42. self.login_as(user=self.user)
  43. out = BytesIO()
  44. f = zipfile.ZipFile(out, "w")
  45. f.write(get_fixture_path("unreal_crash.sym"), "crash.sym")
  46. f.close()
  47. response = self.client.post(
  48. url,
  49. {
  50. "file": SimpleUploadedFile(
  51. "symbols.zip", out.getvalue(), content_type="application/zip"
  52. )
  53. },
  54. format="multipart",
  55. )
  56. assert response.status_code == 201, response.content
  57. assert len(response.data) == 1
  58. def unreal_crash_test_impl(self, filename):
  59. self.project.update_option("sentry:store_crash_reports", STORE_CRASH_REPORTS_ALL)
  60. self.upload_symbols()
  61. # attachments feature has to be on for the files extract stick around
  62. with self.feature("organizations:event-attachments"):
  63. with open(filename, "rb") as f:
  64. resp = self._postUnrealWithHeader(f.read())
  65. assert resp.status_code == 200
  66. event_id = resp.content
  67. event = eventstore.get_event_by_id(self.project.id, event_id)
  68. self.insta_snapshot(
  69. {
  70. "contexts": event.data.get("contexts"),
  71. "exception": event.data.get("exception"),
  72. "stacktrace": event.data.get("stacktrace"),
  73. "threads": event.data.get("threads"),
  74. "extra": event.data.get("extra"),
  75. }
  76. )
  77. return sorted(EventAttachment.objects.filter(event_id=event.event_id), key=lambda x: x.name)
  78. def test_unreal_crash_with_attachments(self):
  79. attachments = self.unreal_crash_test_impl(get_unreal_crash_file())
  80. assert len(attachments) == 4
  81. context, config, minidump, log = attachments
  82. assert context.name == "CrashContext.runtime-xml"
  83. assert context.file.type == "event.attachment"
  84. assert context.file.checksum == "835d3e10db5d1799dc625132c819c047261ddcfb"
  85. assert config.name == "CrashReportClient.ini"
  86. assert config.file.type == "event.attachment"
  87. assert config.file.checksum == "5839c750bdde8cba4d2a979ea857b8154cffdab5"
  88. assert minidump.name == "UE4Minidump.dmp"
  89. assert minidump.file.type == "event.minidump"
  90. assert minidump.file.checksum == "089d9fd3b5c0cc4426339ab46ec3835e4be83c0f"
  91. assert log.name == "YetAnother.log" # Log file is named after the project
  92. assert log.file.type == "event.attachment"
  93. assert log.file.checksum == "24d1c5f75334cd0912cc2670168d593d5fe6c081"
  94. def test_unreal_apple_crash_with_attachments(self):
  95. attachments = self.unreal_crash_test_impl(get_unreal_crash_apple_file())
  96. assert len(attachments) == 6
  97. context, config, diagnostics, log, info, minidump = attachments
  98. assert context.name == "CrashContext.runtime-xml"
  99. assert context.file.type == "event.attachment"
  100. assert context.file.checksum == "5d2723a7d25111645702fcbbcb8e1d038db56c6e"
  101. assert config.name == "CrashReportClient.ini"
  102. assert config.file.type == "event.attachment"
  103. assert config.file.checksum == "4d6a2736e3e4969a68b7adbe197b05c171c29ea0"
  104. assert diagnostics.name == "Diagnostics.txt"
  105. assert diagnostics.file.type == "event.attachment"
  106. assert diagnostics.file.checksum == "aa271bf4e307a78005410234081945352e8fb236"
  107. assert log.name == "YetAnotherMac.log" # Log file is named after the project
  108. assert log.file.type == "event.attachment"
  109. assert log.file.checksum == "735e751a8b6b943dbc0abce0e6d096f4d48a0c1e"
  110. assert info.name == "info.txt"
  111. assert info.file.type == "event.attachment"
  112. assert info.file.checksum == "279b27ac5d0e6792d088e0662ce1a18413b772bc"
  113. assert minidump.name == "minidump.dmp"
  114. assert minidump.file.type == "event.applecrashreport"
  115. assert minidump.file.checksum == "728d0f4b09cf5a7942da3893b6db79ac842b701a"