123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- from __future__ import absolute_import
- import pytest
- import zipfile
- from sentry.utils.compat.mock import patch
- from six import BytesIO
- from django.core.urlresolvers import reverse
- from django.core.files.uploadedfile import SimpleUploadedFile
- from django.test import override_settings
- from sentry import eventstore
- from sentry.testutils import TransactionTestCase
- from sentry.models import EventAttachment
- from sentry.lang.native.utils import STORE_CRASH_REPORTS_ALL
- from tests.symbolicator import get_fixture_path, insta_snapshot_stacktrace_data
- # IMPORTANT:
- # For these tests to run, write `symbolicator.enabled: true` into your
- # `~/.sentry/config.yml` and run `sentry devservices up`
- @override_settings(ALLOWED_HOSTS=["localhost", "testserver", "host.docker.internal"])
- class SymbolicatorMinidumpIntegrationTest(TransactionTestCase):
- @pytest.fixture(autouse=True)
- def initialize(self, live_server):
- self.project.update_option("sentry:builtin_symbol_sources", [])
- new_prefix = live_server.url
- with patch("sentry.auth.system.is_internal_ip", return_value=True), self.options(
- {"system.url-prefix": new_prefix}
- ):
- # Run test case:
- yield
- def upload_symbols(self):
- url = reverse(
- "sentry-api-0-dsym-files",
- kwargs={
- "organization_slug": self.project.organization.slug,
- "project_slug": self.project.slug,
- },
- )
- self.login_as(user=self.user)
- out = BytesIO()
- f = zipfile.ZipFile(out, "w")
- f.write(get_fixture_path("windows.sym"), "crash.sym")
- f.close()
- response = self.client.post(
- url,
- {
- "file": SimpleUploadedFile(
- "symbols.zip", out.getvalue(), content_type="application/zip"
- )
- },
- format="multipart",
- )
- assert response.status_code == 201, response.content
- assert len(response.data) == 1
- def test_full_minidump(self):
- self.project.update_option("sentry:store_crash_reports", STORE_CRASH_REPORTS_ALL)
- self.upload_symbols()
- with self.feature("organizations:event-attachments"):
- attachment = BytesIO(b"Hello World!")
- attachment.name = "hello.txt"
- with open(get_fixture_path("windows.dmp"), "rb") as f:
- resp = self._postMinidumpWithHeader(
- f, {"sentry[logger]": "test-logger", "some_file": attachment}
- )
- assert resp.status_code == 200
- event_id = resp.content
- event = eventstore.get_event_by_id(self.project.id, event_id)
- insta_snapshot_stacktrace_data(self, event.data)
- assert event.data.get("logger") == "test-logger"
- # assert event.data.get("extra") == {"foo": "bar"}
- attachments = sorted(
- EventAttachment.objects.filter(event_id=event.event_id), key=lambda x: x.name
- )
- hello, minidump = attachments
- assert hello.name == "hello.txt"
- assert hello.file.type == "event.attachment"
- assert hello.file.checksum == "2ef7bde608ce5404e97d5f042f95f89f1c232871"
- assert minidump.name == "windows.dmp"
- assert minidump.file.type == "event.minidump"
- assert minidump.file.checksum == "74bb01c850e8d65d3ffbc5bad5cabc4668fce247"
- def test_full_minidump_json_extra(self):
- self.project.update_option("sentry:store_crash_reports", STORE_CRASH_REPORTS_ALL)
- self.upload_symbols()
- with self.feature("organizations:event-attachments"):
- with open(get_fixture_path("windows.dmp"), "rb") as f:
- resp = self._postMinidumpWithHeader(
- f, {"sentry": '{"logger":"test-logger"}', "foo": "bar"}
- )
- assert resp.status_code == 200
- event_id = resp.content
- event = eventstore.get_event_by_id(self.project.id, event_id)
- assert event.data.get("logger") == "test-logger"
- assert event.data.get("extra") == {"foo": "bar"}
- # Other assertions are performed by `test_full_minidump`
- def test_full_minidump_invalid_extra(self):
- self.project.update_option("sentry:store_crash_reports", STORE_CRASH_REPORTS_ALL)
- self.upload_symbols()
- with self.feature("organizations:event-attachments"):
- with open(get_fixture_path("windows.dmp"), "rb") as f:
- resp = self._postMinidumpWithHeader(
- f, {"sentry": "{{{{", "foo": "bar"} # invalid sentry JSON
- )
- assert resp.status_code == 200
- event_id = resp.content
- event = eventstore.get_event_by_id(self.project.id, event_id)
- assert not event.data.get("logger")
- assert event.data.get("extra") == {"foo": "bar"}
- # Other assertions are performed by `test_full_minidump`
- def test_raw_minidump(self):
- self.project.update_option("sentry:store_crash_reports", STORE_CRASH_REPORTS_ALL)
- self.upload_symbols()
- with self.feature("organizations:event-attachments"):
- with open(get_fixture_path("windows.dmp"), "rb") as f:
- # Send as raw request body instead of multipart/form-data
- resp = self._postMinidumpWithHeader(f, raw=True)
- assert resp.status_code == 200
- event_id = resp.content
- event = eventstore.get_event_by_id(self.project.id, event_id)
- insta_snapshot_stacktrace_data(self, event.data)
- def test_missing_dsym(self):
- with self.feature("organizations:event-attachments"):
- with open(get_fixture_path("windows.dmp"), "rb") as f:
- resp = self._postMinidumpWithHeader(f, {"sentry[logger]": "test-logger"})
- assert resp.status_code == 200
- event_id = resp.content
- event = eventstore.get_event_by_id(self.project.id, event_id)
- insta_snapshot_stacktrace_data(self, event.data)
- assert not EventAttachment.objects.filter(event_id=event.event_id)
|