Browse Source

test(sourcemaps): Parametrize SourceMap processing tests to use symbolicator (#46258)

This PR introduces a unified way to run parametrized tests that should
be run via the old JS processor _and_ new Symbolicator processing
pipeline. It does so by introducing `process_with_symbolicator` fixture
which can be requested in any test case.

Note that parametrized tests have to use the `TestName` format, and not
a class-based one that inherits from the `BaseTestCase`.

Tests rely on the latest release of Symbolicator. At the time of filling
this PR, it has to include all changes up to, and including
https://github.com/getsentry/symbolicator/commit/64eda2ce62126e4d0099be05d642492ebe178b26
Kamil Ogórek 1 year ago
parent
commit
0042e02db2

+ 2 - 0
Makefile

@@ -153,9 +153,11 @@ backend-typing:
 	mypy --strict --warn-unreachable --config-file mypy.ini
 	@echo ""
 
+# JavaScript relay tests are meant to be run within Symbolicator test suite, as they are parametrized to verify both processing pipelines during migration process.
 test-symbolicator:
 	@echo "--> Running symbolicator tests"
 	pytest tests/symbolicator -vv --cov . --cov-report="xml:.artifacts/symbolicator.coverage.xml"
+	pytest tests/relay_integration/lang/javascript/ -vv -m symbolicator
 	@echo ""
 
 test-chartcuterie:

+ 2 - 1
pyproject.toml

@@ -22,8 +22,9 @@ addopts = "-ra --tb=short --strict-markers -p no:celery"
 # TODO: --import-mode=importlib will become the default soon,
 # currently we have a few relative imports that don't work with that.
 markers = [
-    "snuba: mark a test as requiring snuba",
+    "snuba: test requires access to snuba",
     "sentry_metrics: test requires access to sentry metrics",
+    "symbolicator: test requires access to symbolicator",
 ]
 selenium_driver = "chrome"
 filterwarnings = [

+ 0 - 1
src/sentry/api/endpoints/artifact_lookup.py

@@ -136,7 +136,6 @@ class ProjectArtifactLookupEndpoint(ProjectEndpoint):
                     "url": url_constructor.url_for_file_id(release_file.file.id),
                     # The `name` is the url/abs_path of the file,
                     # as in: `"~/path/to/file.min.js"`.
-                    # FIXME: Should this be the `ReleaseFile.name` or `File.name`?
                     "abs_path": release_file.name,
                     # These headers should ideally include the `Sourcemap` reference
                     "headers": release_file.file.headers,

+ 4 - 2
src/sentry/lang/javascript/processing.py

@@ -45,8 +45,10 @@ def _merge_frame(new_frame, symbolicated):
     if symbolicated.get("post_context"):
         new_frame["post_context"] = symbolicated["post_context"]
     if symbolicated.get("status"):
-        frame_meta = new_frame.setdefault("data", {})
-        frame_meta["symbolicator_status"] = symbolicated["status"]
+        new_frame.setdefault("data", {})
+        # NOTE: We don't need this currently, and it's not clear whether we'll use it at all.
+        # frame_meta = new_frame.setdefault("data", {})
+        # frame_meta["symbolicator_status"] = symbolicated["status"]
 
     return new_frame
 

+ 21 - 0
src/sentry/testutils/skips.py

@@ -77,3 +77,24 @@ def relay_is_available():
 requires_relay = pytest.mark.skipif(
     not relay_is_available(), reason="requires relay server running"
 )
+
+
+def symbolicator_is_available():
+    from sentry import options
+
+    if "symbolicator" in _service_status:
+        return _service_status["symbolicator"]
+    try:
+        parsed = urlparse(options.get("symbolicator.options")["url"])
+        with socket.create_connection((parsed.hostname, parsed.port), 1.0):
+            pass
+    except OSError:
+        _service_status["symbolicator"] = False
+    else:
+        _service_status["symbolicator"] = True
+    return _service_status["symbolicator"]
+
+
+requires_symbolicator = pytest.mark.skipif(
+    not symbolicator_is_available(), reason="requires symbolicator server running"
+)

+ 12 - 0
src/sentry/utils/pytest/fixtures.py

@@ -449,3 +449,15 @@ def set_sentry_option():
 def django_cache():
     yield cache
     cache.clear()
+
+
+# NOTE:
+# If you are using a local instance of Symbolicator, you may need to either change `system.url-prefix`
+# to `system.internal-url-prefix` or add `127.0.0.1 host.docker.internal` entry to your `/etc/hosts`.
+@pytest.fixture(ids=["without_symbolicator", "with_symbolicator"], params=[0, 1])
+def process_with_symbolicator(request, set_sentry_option, live_server):
+    with set_sentry_option("system.url-prefix", live_server.url), set_sentry_option(
+        "symbolicator.sourcemaps-processing-sample-rate", request.param
+    ):
+        # Run test case
+        yield request.param

+ 46 - 27
tests/relay_integration/lang/javascript/test_example.py

@@ -1,13 +1,24 @@
 import os
 
-import responses
+import pytest
 
-from sentry.testutils import RelayStoreHelper, TransactionTestCase
+from sentry.models import File, Release, ReleaseFile
+from sentry.testutils import RelayStoreHelper
 from sentry.testutils.helpers.datetime import before_now, iso_format
+from sentry.testutils.skips import requires_symbolicator
+
+# IMPORTANT:
+#
+# This test suite requires Symbolicator in order to run correctly.
+# Set `symbolicator.enabled: true` in your `~/.sentry/config.yml` and run `sentry devservices up`
+#
+# If you are using a local instance of Symbolicator, you need to either change `system.url-prefix` to `system.internal-url-prefix`
+# inside `process_with_symbolicator` fixture inside `src/sentry/utils/pytest/fixtures.py`,
+# or add `127.0.0.1 host.docker.internal` entry to your `/etc/hosts`
 
 
 def get_fixture_path(name):
-    return os.path.join(os.path.dirname(__file__), "fixtures", name)
+    return os.path.join(os.path.dirname(__file__), "fixtures/example", name)
 
 
 def load_fixture(name):
@@ -15,35 +26,43 @@ def load_fixture(name):
         return f.read()
 
 
-class ExampleTestCase(RelayStoreHelper, TransactionTestCase):
-    @responses.activate
-    def test_sourcemap_expansion(self):
-        responses.add(
-            responses.GET,
-            "http://example.com/test.js",
-            body=load_fixture("example/test.js"),
-            content_type="application/javascript",
-        )
-        responses.add(
-            responses.GET,
-            "http://example.com/test.min.js",
-            body=load_fixture("example/test.min.js"),
-            content_type="application/javascript",
-        )
-        responses.add(
-            responses.GET,
-            "http://example.com/test.min.js.map",
-            body=load_fixture("example/test.min.js.map"),
-            content_type="application/json",
-        )
-        responses.add(responses.GET, "http://example.com/index.html", body="Not Found", status=404)
+@pytest.mark.django_db(transaction=True)
+class TestExample(RelayStoreHelper):
+    @pytest.fixture(autouse=True)
+    def initialize(self, default_projectkey, default_project):
+        self.project = default_project
+        self.projectkey = default_projectkey
+        self.project.update_option("sentry:scrape_javascript", False)
 
-        min_ago = iso_format(before_now(minutes=1))
+    @requires_symbolicator
+    @pytest.mark.symbolicator
+    def test_sourcemap_expansion(self, process_with_symbolicator):
+        release = Release.objects.create(
+            organization_id=self.project.organization_id, version="abc"
+        )
+        release.add_project(self.project)
+
+        for file in ["test.min.js", "test.js", "test.min.js.map"]:
+            with open(get_fixture_path(file), "rb") as f:
+                f1 = File.objects.create(
+                    name=file,
+                    type="release.file",
+                    headers={},
+                )
+                f1.putfile(f)
+
+            ReleaseFile.objects.create(
+                name=f"http://example.com/{f1.name}",
+                release_id=release.id,
+                organization_id=self.project.organization_id,
+                file=f1,
+            )
 
         data = {
-            "timestamp": min_ago,
+            "timestamp": iso_format(before_now(minutes=1)),
             "message": "hello",
             "platform": "javascript",
+            "release": "abc",
             "exception": {
                 "values": [
                     {

+ 186 - 112
tests/relay_integration/lang/javascript/test_plugin.py

@@ -5,6 +5,7 @@ from io import BytesIO
 from unittest.mock import patch
 from uuid import uuid4
 
+import pytest
 import responses
 from django.utils.encoding import force_bytes
 
@@ -19,10 +20,20 @@ from sentry.models import (
     SourceFileType,
 )
 from sentry.models.releasefile import update_artifact_index
-from sentry.testutils import RelayStoreHelper, SnubaTestCase, TransactionTestCase
+from sentry.testutils import RelayStoreHelper
 from sentry.testutils.helpers.datetime import before_now, iso_format
+from sentry.testutils.skips import requires_symbolicator
 from sentry.utils import json
 
+# IMPORTANT:
+#
+# This test suite requires Symbolicator in order to run correctly.
+# Set `symbolicator.enabled: true` in your `~/.sentry/config.yml` and run `sentry devservices up`
+#
+# If you are using a local instance of Symbolicator, you need to either change `system.url-prefix` to `system.internal-url-prefix`
+# inside `process_with_symbolicator` fixture inside `src/sentry/utils/pytest/fixtures.py`,
+# or add `127.0.0.1 host.docker.internal` entry to your `/etc/hosts`
+
 BASE64_SOURCEMAP = "data:application/json;base64," + (
     b64encode(
         b'{"version":3,"file":"generated.js","sources":["/test.js"],"names":[],"mappings":"AAAA","sourcesContent":['
@@ -44,10 +55,16 @@ def load_fixture(name):
         return fp.read()
 
 
-class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTestCase):
-    def setUp(self):
-        super().setUp()
+@pytest.mark.django_db(transaction=True)
+class TestJavascriptIntegration(RelayStoreHelper):
+    @pytest.fixture(autouse=True)
+    def initialize(self, default_projectkey, default_project):
+        self.project = default_project
+        self.projectkey = default_projectkey
+        self.organization = self.project.organization
         self.min_ago = iso_format(before_now(minutes=1))
+        # We disable scraping per-test when necessary.
+        self.project.update_option("sentry:scrape_javascript", True)
 
     def test_adds_contexts_without_device(self):
         data = {
@@ -365,38 +382,36 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
             == "foo: an unexpected failure occurred while trying to obtain metadata information"
         )
 
-    @responses.activate
-    def test_sourcemap_source_expansion(self):
-        responses.add(
-            responses.GET,
-            "http://example.com/file.min.js",
-            body=load_fixture("file.min.js"),
-            content_type="application/javascript; charset=utf-8",
-        )
-        responses.add(
-            responses.GET,
-            "http://example.com/file1.js",
-            body=load_fixture("file1.js"),
-            content_type="application/javascript; charset=utf-8",
-        )
-        responses.add(
-            responses.GET,
-            "http://example.com/file2.js",
-            body=load_fixture("file2.js"),
-            content_type="application/javascript; charset=utf-8",
-        )
-        responses.add(
-            responses.GET,
-            "http://example.com/file.sourcemap.js",
-            body=load_fixture("file.sourcemap.js"),
-            content_type="application/javascript; charset=utf-8",
+    @requires_symbolicator
+    @pytest.mark.symbolicator
+    def test_sourcemap_source_expansion(self, process_with_symbolicator):
+        self.project.update_option("sentry:scrape_javascript", False)
+        release = Release.objects.create(
+            organization_id=self.project.organization_id, version="abc"
         )
-        responses.add(responses.GET, "http://example.com/index.html", body="Not Found", status=404)
+        release.add_project(self.project)
+
+        for file in ["file.min.js", "file1.js", "file2.js", "file.sourcemap.js"]:
+            with open(get_fixture_path(file), "rb") as f:
+                f1 = File.objects.create(
+                    name=file,
+                    type="release.file",
+                    headers={},
+                )
+                f1.putfile(f)
+
+            ReleaseFile.objects.create(
+                name=f"http://example.com/{f1.name}",
+                release_id=release.id,
+                organization_id=self.project.organization_id,
+                file=f1,
+            )
 
         data = {
             "timestamp": self.min_ago,
             "message": "hello",
             "platform": "javascript",
+            "release": "abc",
             "exception": {
                 "values": [
                     {
@@ -427,9 +442,13 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
 
         event = self.post_and_retrieve_event(data)
 
-        assert event.data["errors"] == [
-            {"type": "js_no_source", "url": "http//example.com/index.html"}
-        ]
+        # FIXME: Unify this assertion once we add error mapping.
+        if process_with_symbolicator:
+            assert "errors" not in event.data
+        else:
+            assert event.data["errors"] == [
+                {"type": "js_no_source", "url": "http//example.com/index.html"}
+            ]
 
         exception = event.interfaces["exception"]
         frame_list = exception.values[0].stacktrace.frames
@@ -438,7 +457,10 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
         assert frame.pre_context == ["function add(a, b) {", '\t"use strict";']
         expected = "\treturn a + b; // fôo"
         assert frame.context_line == expected
-        assert frame.post_context == ["}", ""]
+        if process_with_symbolicator:
+            assert frame.post_context == ["}"]
+        else:
+            assert frame.post_context == ["}", ""]
 
         raw_frame_list = exception.values[0].raw_stacktrace.frames
         raw_frame = raw_frame_list[0]
@@ -448,33 +470,46 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
             == 'function add(a,b){"use strict";return a+b}function multiply(a,b){"use strict";return a*b}function '
             'divide(a,b){"use strict";try{return multip {snip}'
         )
-        assert raw_frame.post_context == ["//@ sourceMappingURL=file.sourcemap.js", ""]
+        if process_with_symbolicator:
+            assert raw_frame.post_context == ["//@ sourceMappingURL=file.sourcemap.js"]
+        else:
+            assert raw_frame.post_context == ["//@ sourceMappingURL=file.sourcemap.js", ""]
         assert raw_frame.lineno == 1
 
         # Since we couldn't expand source for the 2nd frame, both
         # its raw and original form should be identical
         assert raw_frame_list[1] == frame_list[1]
 
-    @responses.activate
-    def test_sourcemap_embedded_source_expansion(self):
-        responses.add(
-            responses.GET,
-            "http://example.com/embedded.js",
-            body=load_fixture("embedded.js"),
-            content_type="application/javascript; charset=utf-8",
-        )
-        responses.add(
-            responses.GET,
-            "http://example.com/embedded.js.map",
-            body=load_fixture("embedded.js.map"),
-            content_type="application/json; charset=utf-8",
+    @requires_symbolicator
+    @pytest.mark.symbolicator
+    def test_sourcemap_embedded_source_expansion(self, process_with_symbolicator):
+        self.project.update_option("sentry:scrape_javascript", False)
+        release = Release.objects.create(
+            organization_id=self.project.organization_id, version="abc"
         )
-        responses.add(responses.GET, "http://example.com/index.html", body="Not Found", status=404)
+        release.add_project(self.project)
+
+        for file in ["embedded.js", "embedded.js.map"]:
+            with open(get_fixture_path(file), "rb") as f:
+                f1 = File.objects.create(
+                    name=file,
+                    type="release.file",
+                    headers={},
+                )
+                f1.putfile(f)
+
+            ReleaseFile.objects.create(
+                name=f"http://example.com/{f1.name}",
+                release_id=release.id,
+                organization_id=self.project.organization_id,
+                file=f1,
+            )
 
         data = {
             "timestamp": self.min_ago,
             "message": "hello",
             "platform": "javascript",
+            "release": "abc",
             "exception": {
                 "values": [
                     {
@@ -505,9 +540,13 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
 
         event = self.post_and_retrieve_event(data)
 
-        assert event.data["errors"] == [
-            {"type": "js_no_source", "url": "http//example.com/index.html"}
-        ]
+        # FIXME: Unify this assertion once we add error mapping.
+        if process_with_symbolicator:
+            assert "errors" not in event.data
+        else:
+            assert event.data["errors"] == [
+                {"type": "js_no_source", "url": "http//example.com/index.html"}
+            ]
 
         exception = event.interfaces["exception"]
         frame_list = exception.values[0].stacktrace.frames
@@ -516,10 +555,14 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
         assert frame.pre_context == ["function add(a, b) {", '\t"use strict";']
         expected = "\treturn a + b; // fôo"
         assert frame.context_line == expected
-        assert frame.post_context == ["}", ""]
-
-    @responses.activate
-    def test_sourcemap_nofiles_source_expansion(self):
+        if process_with_symbolicator:
+            assert frame.post_context == ["}"]
+        else:
+            assert frame.post_context == ["}", ""]
+
+    @requires_symbolicator
+    @pytest.mark.symbolicator
+    def test_sourcemap_nofiles_source_expansion(self, process_with_symbolicator):
         project = self.project
         release = Release.objects.create(organization_id=project.organization_id, version="abc")
         release.add_project(project)
@@ -579,39 +622,41 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
         assert frame.abs_path == "app:///nofiles.js"
         assert frame.pre_context == ["function add(a, b) {", '\t"use strict";']
         assert frame.context_line == "\treturn a + b; // fôo"
-        assert frame.post_context == ["}", ""]
-
-    @responses.activate
-    def test_indexed_sourcemap_source_expansion(self):
-        responses.add(
-            responses.GET,
-            "http://example.com/indexed.min.js",
-            body=load_fixture("indexed.min.js"),
-            content_type="application/javascript; charset=utf-8",
-        )
-        responses.add(
-            responses.GET,
-            "http://example.com/file1.js",
-            body=load_fixture("file1.js"),
-            content_type="application/javascript; charset=utf-8",
-        )
-        responses.add(
-            responses.GET,
-            "http://example.com/file2.js",
-            body=load_fixture("file2.js"),
-            content_type="application/javascript; charset=utf-8",
-        )
-        responses.add(
-            responses.GET,
-            "http://example.com/indexed.sourcemap.js",
-            body=load_fixture("indexed.sourcemap.js"),
-            content_type="application/json; charset=utf-8",
+        if process_with_symbolicator:
+            assert frame.post_context == ["}"]
+        else:
+            assert frame.post_context == ["}", ""]
+
+    @requires_symbolicator
+    @pytest.mark.symbolicator
+    def test_indexed_sourcemap_source_expansion(self, process_with_symbolicator):
+        self.project.update_option("sentry:scrape_javascript", False)
+        release = Release.objects.create(
+            organization_id=self.project.organization_id, version="abc"
         )
+        release.add_project(self.project)
+
+        for file in ["indexed.min.js", "file1.js", "file2.js", "indexed.sourcemap.js"]:
+            with open(get_fixture_path(file), "rb") as f:
+                f1 = File.objects.create(
+                    name=file,
+                    type="release.file",
+                    headers={},
+                )
+                f1.putfile(f)
+
+            ReleaseFile.objects.create(
+                name=f"http://example.com/{f1.name}",
+                release_id=release.id,
+                organization_id=self.project.organization_id,
+                file=f1,
+            )
 
         data = {
             "timestamp": self.min_ago,
             "message": "hello",
             "platform": "javascript",
+            "release": "abc",
             "exception": {
                 "values": [
                     {
@@ -649,18 +694,28 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
 
         expected = "\treturn a + b; // fôo"
         assert frame.context_line == expected
-        assert frame.post_context == ["}", ""]
+        if process_with_symbolicator:
+            assert frame.post_context == ["}"]
+        else:
+            assert frame.post_context == ["}", ""]
 
         raw_frame_list = exception.values[0].raw_stacktrace.frames
         raw_frame = raw_frame_list[0]
         assert not raw_frame.pre_context
         assert raw_frame.context_line == 'function add(a,b){"use strict";return a+b}'
-        assert raw_frame.post_context == [
-            'function multiply(a,b){"use strict";return a*b}function divide(a,b){"use strict";try{return multiply('
-            "add(a,b),a,b)/c}catch(e){Raven.captureE {snip}",
-            "//# sourceMappingURL=indexed.sourcemap.js",
-            "",
-        ]
+        if process_with_symbolicator:
+            assert raw_frame.post_context == [
+                'function multiply(a,b){"use strict";return a*b}function divide(a,b){"use strict";try{return multiply('
+                "add(a,b),a,b)/c}catch(e){Raven.captureE {snip}",
+                "//# sourceMappingURL=indexed.sourcemap.js",
+            ]
+        else:
+            assert raw_frame.post_context == [
+                'function multiply(a,b){"use strict";return a*b}function divide(a,b){"use strict";try{return multiply('
+                "add(a,b),a,b)/c}catch(e){Raven.captureE {snip}",
+                "//# sourceMappingURL=indexed.sourcemap.js",
+                "",
+            ]
         assert raw_frame.lineno == 1
 
         frame = frame_list[1]
@@ -681,11 +736,15 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
             == 'function multiply(a,b){"use strict";return a*b}function divide(a,b){"use strict";try{return multiply('
             "add(a,b),a,b)/c}catch(e){Raven.captureE {snip}"
         )
-        assert raw_frame.post_context == ["//# sourceMappingURL=indexed.sourcemap.js", ""]
+        if process_with_symbolicator:
+            assert raw_frame.post_context == ["//# sourceMappingURL=indexed.sourcemap.js"]
+        else:
+            assert raw_frame.post_context == ["//# sourceMappingURL=indexed.sourcemap.js", ""]
         assert raw_frame.lineno == 2
 
-    @responses.activate
-    def test_expansion_via_debug(self):
+    @requires_symbolicator
+    @pytest.mark.symbolicator
+    def test_expansion_via_debug(self, process_with_symbolicator):
         project = self.project
         release = Release.objects.create(organization_id=project.organization_id, version="abc")
         release.add_project(project)
@@ -815,7 +874,10 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
         frame = frame_list[0]
         assert frame.pre_context == ["function add(a, b) {", '\t"use strict";']
         assert frame.context_line == "\treturn a + b; // fôo"
-        assert frame.post_context == ["}", ""]
+        if process_with_symbolicator:
+            assert frame.post_context == ["}"]
+        else:
+            assert frame.post_context == ["}", ""]
 
         frame = frame_list[1]
         assert frame.pre_context == ["function multiply(a, b) {", '\t"use strict";']
@@ -828,8 +890,9 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
             "\t\treturn multiply(add(a, b), a, b) / c;",
         ]
 
-    @responses.activate
-    def test_expansion_via_distribution_release_artifacts(self):
+    @requires_symbolicator
+    @pytest.mark.symbolicator
+    def test_expansion_via_distribution_release_artifacts(self, process_with_symbolicator):
         project = self.project
         release = Release.objects.create(organization_id=project.organization_id, version="abc")
         release.add_project(project)
@@ -861,7 +924,9 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
 
         with open(get_fixture_path("file1.js"), "rb") as f:
             f1 = File.objects.create(
-                name="file1.js", type="release.file", headers={"Content-Type": "application/json"}
+                name="file1.js",
+                type="release.file",
+                headers={"Content-Type": "application/json"},
             )
             f1.putfile(f)
 
@@ -878,7 +943,9 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
 
         with open(get_fixture_path("file2.js"), "rb") as f:
             f2 = File.objects.create(
-                name="file2.js", type="release.file", headers={"Content-Type": "application/json"}
+                name="file2.js",
+                type="release.file",
+                headers={"Content-Type": "application/json"},
             )
             f2.putfile(f)
         ReleaseFile.objects.create(
@@ -896,7 +963,9 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
         # context for the 2nd frame.
         with open(get_fixture_path("empty.js"), "rb") as f:
             f2_empty = File.objects.create(
-                name="empty.js", type="release.file", headers={"Content-Type": "application/json"}
+                name="empty.js",
+                type="release.file",
+                headers={"Content-Type": "application/json"},
             )
             f2_empty.putfile(f)
         ReleaseFile.objects.create(
@@ -966,7 +1035,10 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
         frame = frame_list[0]
         assert frame.pre_context == ["function add(a, b) {", '\t"use strict";']
         assert frame.context_line == "\treturn a + b; // fôo"
-        assert frame.post_context == ["}", ""]
+        if process_with_symbolicator:
+            assert frame.post_context == ["}"]
+        else:
+            assert frame.post_context == ["}", ""]
 
         frame = frame_list[1]
         assert frame.pre_context == ["function multiply(a, b) {", '\t"use strict";']
@@ -1170,17 +1242,17 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
     def test_html_response_for_js(self):
         responses.add(
             responses.GET,
-            "http://example.com/file1.js",
+            "http://example.com/invalid_file1.js",
             body="       <!DOCTYPE html><html><head></head><body></body></html>",
         )
         responses.add(
             responses.GET,
-            "http://example.com/file2.js",
+            "http://example.com/invalid_file2.js",
             body="<!doctype html><html><head></head><body></body></html>",
         )
         responses.add(
             responses.GET,
-            "http://example.com/file.html",
+            "http://example.com/valid_file.html",
             body=(
                 "<!doctype html><html><head></head><body><script>/*legit case*/</script></body></html>"
             ),
@@ -1197,20 +1269,20 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
                         "stacktrace": {
                             "frames": [
                                 {
-                                    "abs_path": "http://example.com/file1.js",
-                                    "filename": "file.min.js",
+                                    "abs_path": "http://example.com/invalid_file1.js",
+                                    "filename": "invalid_file1.js",
                                     "lineno": 1,
                                     "colno": 39,
                                 },
                                 {
-                                    "abs_path": "http://example.com/file2.js",
-                                    "filename": "file.min.js",
+                                    "abs_path": "http://example.com/invalid_file2.js",
+                                    "filename": "invalid_file2.js",
                                     "lineno": 1,
                                     "colno": 39,
                                 },
                                 {
-                                    "abs_path": "http://example.com/file.html",
-                                    "filename": "file.html",
+                                    "abs_path": "http://example.com/valid_file.html",
+                                    "filename": "valid_file.html",
                                     "lineno": 1,
                                     "colno": 1,
                                 },
@@ -1224,8 +1296,8 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
         event = self.post_and_retrieve_event(data)
 
         assert event.data["errors"] == [
-            {"url": "http://example.com/file1.js", "type": "js_invalid_content"},
-            {"url": "http://example.com/file2.js", "type": "js_invalid_content"},
+            {"url": "http://example.com/invalid_file1.js", "type": "js_invalid_content"},
+            {"url": "http://example.com/invalid_file2.js", "type": "js_invalid_content"},
         ]
 
     def _test_expansion_via_release_archive(self, link_sourcemaps: bool):
@@ -1329,7 +1401,9 @@ class JavascriptIntegrationTest(RelayStoreHelper, SnubaTestCase, TransactionTest
     def test_expansion_via_release_archive_no_sourcemap_link(self):
         self._test_expansion_via_release_archive(link_sourcemaps=False)
 
-    def test_node_processing(self):
+    @requires_symbolicator
+    @pytest.mark.symbolicator
+    def test_node_processing(self, process_with_symbolicator):
         project = self.project
         release = Release.objects.create(
             organization_id=project.organization_id, version="nodeabc123"

+ 0 - 137
tests/symbolicator/snapshots/TestSymbolicatorSourceMapIntegration/test_symbolicator_roundtrip/0.pysnap

@@ -1,137 +0,0 @@
----
-created: '2023-03-22T16:27:13.923183Z'
-creator: sentry
-source: tests/symbolicator/test_sourcemap.py
----
-errors:
-- type: js_no_source
-  url: http://example.com/index.html
-exception:
-  values:
-  - raw_stacktrace:
-      frames:
-      - abs_path: http://example.com/test.min.js
-        colno: 64
-        context_line: var makeAFailure=function(){function n(n){}function e(n){throw
-          new Error("failed!")}function r(r){var i=null;if(r.failed){i=e}else{i=n}i(r)}
-          {snip}
-        data:
-          orig_in_app: -1
-        filename: test.min.js
-        function: e
-        in_app: false
-        lineno: 1
-        post_context:
-        - //# sourceMappingURL=test.map
-      - abs_path: http://example.com/test.min.js
-        colno: 136
-        context_line: '{snip} row new Error("failed!")}function r(r){var i=null;if(r.failed){i=e}else{i=n}i(r)}function
-          i(){var n={failed:true,value:42};r(n)}return i}();'
-        data:
-          orig_in_app: -1
-        filename: test.min.js
-        function: r
-        in_app: false
-        lineno: 1
-        post_context:
-        - //# sourceMappingURL=test.map
-      - abs_path: http://example.com/test.min.js
-        colno: 183
-        context_line: '{snip} row new Error("failed!")}function r(r){var i=null;if(r.failed){i=e}else{i=n}i(r)}function
-          i(){var n={failed:true,value:42};r(n)}return i}();'
-        data:
-          orig_in_app: -1
-        filename: test.min.js
-        function: i
-        in_app: false
-        lineno: 1
-        post_context:
-        - //# sourceMappingURL=test.map
-      - abs_path: http://example.com/index.html
-        colno: 7
-        data:
-          orig_in_app: -1
-        filename: index.html
-        function: produceStack
-        in_app: false
-        lineno: 6
-    stacktrace:
-      frames:
-      - abs_path: http://example.com/test.js
-        colno: 11
-        context_line: '    throw new Error(''failed!'');'
-        data:
-          orig_in_app: -1
-          sourcemap: http://example.com/test.map
-        filename: test.js
-        function: onFailure
-        in_app: false
-        lineno: 5
-        module: test
-        post_context:
-        - '  }'
-        - ''
-        - '  function invoke(data) {'
-        - '    var cb = null;'
-        - '    if (data.failed) {'
-        pre_context:
-        - var makeAFailure = (function() {
-        - '  function onSuccess(data) {}'
-        - ''
-        - '  function onFailure(data) {'
-      - abs_path: http://example.com/test.js
-        colno: 5
-        context_line: '    cb(data);'
-        data:
-          orig_in_app: -1
-          sourcemap: http://example.com/test.map
-        filename: test.js
-        function: invoke
-        in_app: false
-        lineno: 15
-        module: test
-        post_context:
-        - '  }'
-        - ''
-        - '  function test() {'
-        - '    var data = {failed: true, value: 42};'
-        - '    invoke(data);'
-        pre_context:
-        - '    if (data.failed) {'
-        - '      cb = onFailure;'
-        - '    } else {'
-        - '      cb = onSuccess;'
-        - '    }'
-      - abs_path: http://example.com/test.js
-        colno: 5
-        context_line: '    invoke(data);'
-        data:
-          orig_in_app: -1
-          sourcemap: http://example.com/test.map
-        filename: test.js
-        function: test
-        in_app: false
-        lineno: 20
-        module: test
-        post_context:
-        - '  }'
-        - ''
-        - '  return test;'
-        - '})();'
-        - ''
-        pre_context:
-        - '    cb(data);'
-        - '  }'
-        - ''
-        - '  function test() {'
-        - '    var data = {failed: true, value: 42};'
-      - abs_path: http://example.com/index.html
-        colno: 7
-        data:
-          orig_in_app: -1
-        filename: index.html
-        function: produceStack
-        in_app: false
-        lineno: 6
-        module: index
-    type: Error

+ 0 - 132
tests/symbolicator/snapshots/TestSymbolicatorSourceMapIntegration/test_symbolicator_roundtrip/1.pysnap

@@ -1,132 +0,0 @@
----
-created: '2023-03-22T16:27:18.884198Z'
-creator: sentry
-source: tests/symbolicator/test_sourcemap.py
----
-errors: []
-exception:
-  values:
-  - raw_stacktrace:
-      frames:
-      - abs_path: http://example.com/test.min.js
-        colno: 64
-        context_line: var makeAFailure=function(){function n(n){}function e(n){throw
-          new Error("failed!")}function r(r){var i=null;if(r.failed){i=e}else{i=n}i(r)}
-          {snip}
-        data:
-          orig_in_app: -1
-        filename: test.min.js
-        function: e
-        in_app: false
-        lineno: 1
-        post_context:
-        - //# sourceMappingURL=test.map
-      - abs_path: http://example.com/test.min.js
-        colno: 136
-        context_line: '{snip} row new Error("failed!")}function r(r){var i=null;if(r.failed){i=e}else{i=n}i(r)}function
-          i(){var n={failed:true,value:42};r(n)}return i}();'
-        data:
-          orig_in_app: -1
-        filename: test.min.js
-        function: r
-        in_app: false
-        lineno: 1
-        post_context:
-        - //# sourceMappingURL=test.map
-      - abs_path: http://example.com/test.min.js
-        colno: 183
-        context_line: '{snip} row new Error("failed!")}function r(r){var i=null;if(r.failed){i=e}else{i=n}i(r)}function
-          i(){var n={failed:true,value:42};r(n)}return i}();'
-        data:
-          orig_in_app: -1
-        filename: test.min.js
-        function: i
-        in_app: false
-        lineno: 1
-        post_context:
-        - //# sourceMappingURL=test.map
-      - abs_path: http://example.com/index.html
-        colno: 7
-        data:
-          orig_in_app: -1
-        filename: index.html
-        function: produceStack
-        in_app: false
-        lineno: 6
-    stacktrace:
-      frames:
-      - abs_path: test.js
-        colno: 11
-        context_line: '    throw new Error(''failed!'');'
-        data:
-          orig_in_app: -1
-          symbolicator_status: symbolicated
-        filename: test.js
-        function: onFailure
-        in_app: false
-        lineno: 5
-        post_context:
-        - '  }'
-        - ''
-        - '  function invoke(data) {'
-        - '    var cb = null;'
-        - '    if (data.failed) {'
-        pre_context:
-        - var makeAFailure = (function() {
-        - '  function onSuccess(data) {}'
-        - ''
-        - '  function onFailure(data) {'
-      - abs_path: test.js
-        colno: 5
-        context_line: '    cb(data);'
-        data:
-          orig_in_app: -1
-          symbolicator_status: symbolicated
-        filename: test.js
-        function: invoke
-        in_app: false
-        lineno: 15
-        post_context:
-        - '  }'
-        - ''
-        - '  function test() {'
-        - '    var data = {failed: true, value: 42};'
-        - '    invoke(data);'
-        pre_context:
-        - '    if (data.failed) {'
-        - '      cb = onFailure;'
-        - '    } else {'
-        - '      cb = onSuccess;'
-        - '    }'
-      - abs_path: test.js
-        colno: 5
-        context_line: '    invoke(data);'
-        data:
-          orig_in_app: -1
-          symbolicator_status: symbolicated
-        filename: test.js
-        function: test
-        in_app: false
-        lineno: 20
-        post_context:
-        - '  }'
-        - ''
-        - '  return test;'
-        - '})();'
-        pre_context:
-        - '    cb(data);'
-        - '  }'
-        - ''
-        - '  function test() {'
-        - '    var data = {failed: true, value: 42};'
-      - abs_path: http://example.com/index.html
-        colno: 7
-        data:
-          orig_in_app: -1
-          symbolicator_status: missing_sourcemap
-        filename: index.html
-        function: produceStack
-        in_app: false
-        lineno: 6
-        module: index
-    type: Error

Some files were not shown because too many files changed in this diff