test_unreal_full.py 5.9 KB

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