|
@@ -1,26 +1,16 @@
|
|
|
-import os.path
|
|
|
import zipfile
|
|
|
from io import BytesIO
|
|
|
from unittest.mock import patch
|
|
|
-from uuid import uuid4
|
|
|
|
|
|
import pytest
|
|
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
|
|
from django.urls import reverse
|
|
|
|
|
|
from sentry import eventstore
|
|
|
-from sentry.models import (
|
|
|
- ArtifactBundle,
|
|
|
- DebugIdArtifactBundle,
|
|
|
- File,
|
|
|
- ProjectDebugFile,
|
|
|
- SourceFileType,
|
|
|
-)
|
|
|
+from sentry.models import File, ProjectDebugFile
|
|
|
from sentry.testutils import RelayStoreHelper, TransactionTestCase
|
|
|
from sentry.testutils.factories import get_fixture_path
|
|
|
from sentry.testutils.helpers.datetime import before_now, iso_format
|
|
|
-from sentry.testutils.helpers.options import override_options
|
|
|
-from sentry.utils import json
|
|
|
from tests.symbolicator import insta_snapshot_native_stacktrace_data, redact_location
|
|
|
|
|
|
# IMPORTANT:
|
|
@@ -73,20 +63,10 @@ REAL_RESOLVING_EVENT_DATA = {
|
|
|
}
|
|
|
|
|
|
|
|
|
-def get_local_fixture_path(name):
|
|
|
- return os.path.join(os.path.dirname(__file__), "fixtures", name)
|
|
|
-
|
|
|
-
|
|
|
-def load_fixture(name):
|
|
|
- with open(get_local_fixture_path(name), "rb") as fp:
|
|
|
- return fp.read()
|
|
|
-
|
|
|
-
|
|
|
class SymbolicatorResolvingIntegrationTest(RelayStoreHelper, TransactionTestCase):
|
|
|
@pytest.fixture(autouse=True)
|
|
|
def initialize(self, live_server):
|
|
|
self.project.update_option("sentry:builtin_symbol_sources", [])
|
|
|
- self.min_ago = iso_format(before_now(minutes=1))
|
|
|
|
|
|
with patch("sentry.auth.system.is_internal_ip", return_value=True), self.options(
|
|
|
{"system.url-prefix": live_server.url}
|
|
@@ -271,155 +251,3 @@ class SymbolicatorResolvingIntegrationTest(RelayStoreHelper, TransactionTestCase
|
|
|
candidates = event.data["debug_meta"]["images"][0]["candidates"]
|
|
|
redact_location(candidates)
|
|
|
self.insta_snapshot(candidates)
|
|
|
-
|
|
|
- def test_resolve_mixed_stack_trace(self):
|
|
|
- # native debug files:
|
|
|
- wasm_file = File.objects.create(
|
|
|
- name="test.wasm", type="default", headers={"Content-Type": "application/wasm"}
|
|
|
- )
|
|
|
-
|
|
|
- with open(get_local_fixture_path("a18fd85d4a4eb893022d6bfad846b1.debug"), "rb") as f:
|
|
|
- wasm_file.putfile(f)
|
|
|
-
|
|
|
- # FIXME(swatinem):
|
|
|
- # We have a problem, and it seems to be serious! :-(
|
|
|
- # The `debug_files` endpoints is using the `ProjectDebugFile.id`, which
|
|
|
- # symbolicator is using for caching etc.
|
|
|
- # Whereas the `artifact_lookup` is using the `File.id`, which symbolicator
|
|
|
- # uses in the same way.
|
|
|
- # These two IDs can have collisions !!!
|
|
|
- # This can happen right here in this fest when you switch the order
|
|
|
- # of creating the native / js files:
|
|
|
- # In that case, the `File.id` would be `1`, the same as the `ProjectDebugFile.id`.
|
|
|
- # In that case, as we are JS-symbolicating first, symbolicator will fetch
|
|
|
- # the bundle with id `1`, and then later on reusing that same cache for
|
|
|
- # the wasm file with id `1`, although the cache now already has the JS
|
|
|
- # bundle cached as id `1`, and tries to reuse that for wasm, which is wrong.
|
|
|
- #
|
|
|
- # The symbolicator cache is also keyed on the `scope` (aka project id),
|
|
|
- # and it is extremely unlikely to have such collisions in production for
|
|
|
- # the same project.
|
|
|
- ProjectDebugFile.objects.create(
|
|
|
- file=wasm_file,
|
|
|
- object_name="test.wasm",
|
|
|
- cpu_name="wasm32",
|
|
|
- project_id=self.project.id,
|
|
|
- debug_id="bda18fd8-5d4a-4eb8-9302-2d6bfad846b1",
|
|
|
- code_id="bda18fd85d4a4eb893022d6bfad846b1",
|
|
|
- )
|
|
|
-
|
|
|
- # JS debug files:
|
|
|
- debug_id = "c941d872-af1f-4f0c-a7ff-ad3d295fe153"
|
|
|
-
|
|
|
- compressed = BytesIO(b"SYSB")
|
|
|
- with zipfile.ZipFile(compressed, "a") as zip_file:
|
|
|
- zip_file.writestr("files/_/_/test.min.js", load_fixture("test.min.js"))
|
|
|
- zip_file.writestr("files/_/_/test.map", load_fixture("test.map"))
|
|
|
-
|
|
|
- zip_file.writestr(
|
|
|
- "manifest.json",
|
|
|
- json.dumps(
|
|
|
- {
|
|
|
- "files": {
|
|
|
- "files/_/_/test.min.js": {
|
|
|
- "url": "~/test.min.js",
|
|
|
- "type": "minified_source",
|
|
|
- "headers": {
|
|
|
- "debug-id": debug_id,
|
|
|
- "sourcemap": "test.map",
|
|
|
- },
|
|
|
- },
|
|
|
- "files/_/_/test.map": {
|
|
|
- "url": "~/file.wc.sourcemap.js",
|
|
|
- "type": "source_map",
|
|
|
- "headers": {
|
|
|
- "debug-id": debug_id,
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
- ),
|
|
|
- )
|
|
|
- compressed.seek(0)
|
|
|
- bundle_file = File.objects.create(name="bundle.zip", type="artifact.bundle")
|
|
|
- bundle_file.putfile(compressed)
|
|
|
-
|
|
|
- artifact_bundle = ArtifactBundle.objects.create(
|
|
|
- organization_id=self.organization.id,
|
|
|
- bundle_id=uuid4(),
|
|
|
- file=bundle_file,
|
|
|
- artifact_count=2,
|
|
|
- )
|
|
|
-
|
|
|
- DebugIdArtifactBundle.objects.create(
|
|
|
- organization_id=self.organization.id,
|
|
|
- debug_id=debug_id,
|
|
|
- artifact_bundle=artifact_bundle,
|
|
|
- source_file_type=SourceFileType.MINIFIED_SOURCE.value,
|
|
|
- )
|
|
|
- DebugIdArtifactBundle.objects.create(
|
|
|
- organization_id=self.organization.id,
|
|
|
- debug_id=debug_id,
|
|
|
- artifact_bundle=artifact_bundle,
|
|
|
- source_file_type=SourceFileType.SOURCE_MAP.value,
|
|
|
- )
|
|
|
-
|
|
|
- data = {
|
|
|
- "timestamp": self.min_ago,
|
|
|
- "message": "hello",
|
|
|
- "platform": "javascript",
|
|
|
- "release": "abc",
|
|
|
- "exception": {
|
|
|
- "values": [
|
|
|
- {
|
|
|
- "type": "Error",
|
|
|
- "stacktrace": {
|
|
|
- "frames": [
|
|
|
- {
|
|
|
- "abs_path": "http://example.com/test.min.js",
|
|
|
- "lineno": 1,
|
|
|
- "colno": 183,
|
|
|
- },
|
|
|
- {
|
|
|
- "platform": "native",
|
|
|
- "instruction_addr": "0x8c",
|
|
|
- "addr_mode": "rel:0",
|
|
|
- },
|
|
|
- ]
|
|
|
- },
|
|
|
- }
|
|
|
- ]
|
|
|
- },
|
|
|
- "debug_meta": {
|
|
|
- "images": [
|
|
|
- {
|
|
|
- "type": "sourcemap",
|
|
|
- "debug_id": debug_id,
|
|
|
- "code_file": "http://example.com/test.min.js",
|
|
|
- },
|
|
|
- {
|
|
|
- "type": "wasm",
|
|
|
- "debug_id": "bda18fd8-5d4a-4eb8-9302-2d6bfad846b1",
|
|
|
- "code_id": "bda18fd85d4a4eb893022d6bfad846b1",
|
|
|
- "debug_file": "file://foo.invalid/demo.wasm",
|
|
|
- },
|
|
|
- ]
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- with override_options({"symbolicator.sourcemaps-processing-sample-rate": 1.0}):
|
|
|
- event = self.post_and_retrieve_event(data)
|
|
|
-
|
|
|
- exception = event.interfaces["exception"]
|
|
|
- frames = exception.values[0].stacktrace.frames
|
|
|
- assert frames[0].abs_path == "http://example.com/test.js"
|
|
|
- assert frames[0].lineno == 20
|
|
|
- assert frames[0].colno == 5
|
|
|
- assert frames[0].context_line == " invoke(data);"
|
|
|
-
|
|
|
- assert frames[1].abs_path == "/Users/mitsuhiko/Development/wasm-example/simple/src/lib.rs"
|
|
|
- assert frames[1].lineno == 19
|
|
|
- assert frames[1].function == "internal_func"
|
|
|
-
|
|
|
- images = event.data["debug_meta"]["images"]
|
|
|
- assert images[1]["debug_status"] == "found"
|