test_payload_full.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. from __future__ import absolute_import
  2. import os
  3. import pytest
  4. import zipfile
  5. from mock import patch
  6. from six import BytesIO
  7. from django.core.urlresolvers import reverse
  8. from django.core.files.uploadedfile import SimpleUploadedFile
  9. from sentry.testutils import TransactionTestCase
  10. from sentry.models import Event, File, ProjectDebugFile
  11. from tests.symbolicator import insta_snapshot_stacktrace_data
  12. REAL_RESOLVING_EVENT_DATA = {
  13. "platform": "cocoa",
  14. "debug_meta": {
  15. "images": [{
  16. "type": "apple",
  17. "arch": "x86_64",
  18. "uuid": "502fc0a5-1ec1-3e47-9998-684fa139dca7",
  19. "image_vmaddr": "0x0000000100000000",
  20. "image_size": 4096,
  21. "image_addr": "0x0000000100000000",
  22. "name": "Foo.app/Contents/Foo"
  23. }],
  24. "sdk_info": {
  25. "dsym_type": "macho",
  26. "sdk_name": "macOS",
  27. "version_major": 10,
  28. "version_minor": 12,
  29. "version_patchlevel": 4,
  30. }
  31. },
  32. "exception": {
  33. "values": [
  34. {
  35. 'stacktrace': {
  36. "frames": [
  37. {
  38. "platform": "foobar",
  39. "function": "hi"
  40. },
  41. {
  42. "function": "unknown",
  43. "instruction_addr": "0x0000000100000fa0"
  44. }
  45. ]
  46. },
  47. "type": "Fail",
  48. "value": "fail"
  49. }
  50. ]
  51. },
  52. }
  53. class ResolvingIntegrationTestBase(object):
  54. def test_real_resolving(self):
  55. url = reverse(
  56. 'sentry-api-0-dsym-files',
  57. kwargs={
  58. 'organization_slug': self.project.organization.slug,
  59. 'project_slug': self.project.slug,
  60. }
  61. )
  62. self.login_as(user=self.user)
  63. out = BytesIO()
  64. f = zipfile.ZipFile(out, 'w')
  65. f.write(os.path.join(os.path.dirname(__file__), 'fixtures', 'hello.dsym'),
  66. 'dSYM/hello')
  67. f.close()
  68. response = self.client.post(
  69. url, {
  70. 'file':
  71. SimpleUploadedFile('symbols.zip', out.getvalue(), content_type='application/zip'),
  72. },
  73. format='multipart'
  74. )
  75. assert response.status_code == 201, response.content
  76. assert len(response.data) == 1
  77. resp = self._postWithHeader(dict(project=self.project.id, **REAL_RESOLVING_EVENT_DATA))
  78. assert resp.status_code == 200
  79. event = Event.objects.get()
  80. assert event.data['culprit'] == 'main'
  81. insta_snapshot_stacktrace_data(self, event.data)
  82. def test_debug_id_resolving(self):
  83. file = File.objects.create(
  84. name='crash.pdb',
  85. type='default',
  86. headers={'Content-Type': 'text/x-breakpad'},
  87. )
  88. path = os.path.join(os.path.dirname(__file__), 'fixtures', 'windows.sym')
  89. with open(path) as f:
  90. file.putfile(f)
  91. ProjectDebugFile.objects.create(
  92. file=file,
  93. object_name='crash.pdb',
  94. cpu_name='x86',
  95. project=self.project,
  96. debug_id='3249d99d-0c40-4931-8610-f4e4fb0b6936-1',
  97. code_id='5AB380779000',
  98. )
  99. self.login_as(user=self.user)
  100. event_data = {
  101. 'contexts': {
  102. 'device': {
  103. 'arch': 'x86'
  104. },
  105. 'os': {
  106. 'build': u'',
  107. 'name': 'Windows',
  108. 'type': 'os',
  109. 'version': u'10.0.14393'
  110. }
  111. },
  112. 'debug_meta': {
  113. 'images': [
  114. {
  115. 'id': u'3249d99d-0c40-4931-8610-f4e4fb0b6936-1',
  116. 'image_addr': '0x2a0000',
  117. 'image_size': 36864,
  118. 'name': u'C:\\projects\\breakpad-tools\\windows\\Release\\crash.exe',
  119. 'type': 'symbolic'
  120. }
  121. ]
  122. },
  123. 'exception': {
  124. 'stacktrace': {
  125. 'frames': [
  126. {
  127. 'function': '<unknown>',
  128. 'instruction_addr': '0x2a2a3d',
  129. 'package': u'C:\\projects\\breakpad-tools\\windows\\Release\\crash.exe'
  130. }
  131. ]
  132. },
  133. 'thread_id': 1636,
  134. 'type': u'EXCEPTION_ACCESS_VIOLATION_WRITE',
  135. 'value': u'Fatal Error: EXCEPTION_ACCESS_VIOLATION_WRITE'
  136. },
  137. 'platform': 'native'
  138. }
  139. resp = self._postWithHeader(event_data)
  140. assert resp.status_code == 200
  141. event = Event.objects.get()
  142. assert event.data['culprit'] == 'main'
  143. insta_snapshot_stacktrace_data(self, event.data)
  144. def test_missing_dsym(self):
  145. self.login_as(user=self.user)
  146. resp = self._postWithHeader(dict(project=self.project.id, **REAL_RESOLVING_EVENT_DATA))
  147. assert resp.status_code == 200
  148. event = Event.objects.get()
  149. assert event.data['culprit'] == 'unknown'
  150. insta_snapshot_stacktrace_data(self, event.data)
  151. def test_missing_debug_images(self):
  152. self.login_as(user=self.user)
  153. payload = dict(project=self.project.id, **REAL_RESOLVING_EVENT_DATA)
  154. del payload['debug_meta']
  155. resp = self._postWithHeader(payload)
  156. assert resp.status_code == 200
  157. event = Event.objects.get()
  158. assert event.data['culprit'] == 'unknown'
  159. insta_snapshot_stacktrace_data(self, event.data)
  160. class SymbolicatorResolvingIntegrationTest(ResolvingIntegrationTestBase, TransactionTestCase):
  161. # For these tests to run, write `symbolicator.enabled: true` into your
  162. # `~/.sentry/config.yml` and run `sentry devservices up`
  163. @pytest.fixture(autouse=True)
  164. def initialize(self, live_server):
  165. new_prefix = live_server.url
  166. with patch('sentry.auth.system.is_internal_ip', return_value=True), \
  167. self.options({"system.url-prefix": new_prefix}):
  168. # Run test case:
  169. yield