123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913 |
- from __future__ import annotations
- import zipfile
- from io import BytesIO
- from os.path import join
- from tempfile import TemporaryFile
- from typing import Any
- import pytest
- from django.core.files.uploadedfile import SimpleUploadedFile
- from django.urls import reverse
- from sentry.lang.javascript.processing import _handles_frame as is_valid_javascript_frame
- from sentry.models.files.file import File
- from sentry.models.project import Project
- from sentry.models.projectkey import ProjectKey, UseCase
- from sentry.models.release import Release
- from sentry.models.releasefile import ReleaseFile
- from sentry.profiles.task import (
- Profile,
- _calculate_profile_duration_ms,
- _deobfuscate,
- _deobfuscate_locally,
- _deobfuscate_using_symbolicator,
- _normalize,
- _process_symbolicator_results_for_sample,
- _set_frames_platform,
- _symbolicate_profile,
- get_metrics_dsn,
- )
- from sentry.testutils.cases import TransactionTestCase
- from sentry.testutils.factories import Factories, get_fixture_path
- from sentry.testutils.pytest.fixtures import django_db_all
- from sentry.testutils.skips import requires_symbolicator
- from sentry.utils import json
- PROFILES_FIXTURES_PATH = get_fixture_path("profiles")
- PROGUARD_UUID = "6dc7fdb0-d2fb-4c8e-9d6b-bb1aa98929b1"
- PROGUARD_SOURCE = b"""\
- # compiler: R8
- # compiler_version: 2.0.74
- # min_api: 16
- # pg_map_id: 5b46fdc
- # common_typos_disable
- # {"id":"com.android.tools.r8.mapping","version":"1.0"}
- org.slf4j.helpers.Util$ClassContextSecurityManager -> org.a.b.g$a:
- 65:65:void <init>() -> <init>
- 67:67:java.lang.Class[] getClassContext() -> a
- 69:69:java.lang.Class[] getExtraClassContext() -> a
- 65:65:void <init>(org.slf4j.helpers.Util$1) -> <init>
- """
- PROGUARD_INLINE_UUID = "d748e578-b3d1-5be5-b0e5-a42e8c9bf8e0"
- PROGUARD_INLINE_SOURCE = b"""\
- # compiler: R8
- # compiler_version: 2.0.74
- # min_api: 16
- # pg_map_id: 5b46fdc
- # common_typos_disable
- # {"id":"com.android.tools.r8.mapping","version":"1.0"}
- $r8$backportedMethods$utility$Objects$2$equals -> a:
- boolean equals(java.lang.Object,java.lang.Object) -> a
- $r8$twr$utility -> b:
- void $closeResource(java.lang.Throwable,java.lang.Object) -> a
- android.support.v4.app.RemoteActionCompatParcelizer -> android.support.v4.app.RemoteActionCompatParcelizer:
- 1:1:void <init>():11:11 -> <init>
- io.sentry.sample.-$$Lambda$r3Avcbztes2hicEObh02jjhQqd4 -> e.a.c.a:
- io.sentry.sample.MainActivity f$0 -> b
- io.sentry.sample.MainActivity -> io.sentry.sample.MainActivity:
- 1:1:void <init>():15:15 -> <init>
- 1:1:boolean onCreateOptionsMenu(android.view.Menu):60:60 -> onCreateOptionsMenu
- 1:1:boolean onOptionsItemSelected(android.view.MenuItem):69:69 -> onOptionsItemSelected
- 2:2:boolean onOptionsItemSelected(android.view.MenuItem):76:76 -> onOptionsItemSelected
- 1:1:void bar():54:54 -> t
- 1:1:void foo():44 -> t
- 1:1:void onClickHandler(android.view.View):40 -> t
- """
- PROGUARD_BUG_UUID = "071207ac-b491-4a74-957c-2c94fd9594f2"
- PROGUARD_BUG_SOURCE = b"x"
- def load_profile(name):
- path = join(PROFILES_FIXTURES_PATH, name)
- with open(path) as f:
- return json.loads(f.read())
- def load_proguard(project, proguard_uuid, proguard_source):
- with TemporaryFile() as tf:
- tf.write(proguard_source)
- tf.seek(0)
- file = Factories.create_file(
- name=proguard_uuid,
- type="project.dif",
- headers={"Content-Type": "proguard"},
- )
- file.putfile(tf)
- return Factories.create_dif_file(
- project,
- file=file,
- debug_id=proguard_uuid,
- object_name="proguard-mapping",
- data={"features": ["mapping"]},
- )
- @pytest.fixture
- def owner():
- return Factories.create_user()
- @pytest.fixture
- def organization(owner):
- return Factories.create_organization(owner=owner)
- @pytest.fixture
- def team(organization, owner):
- team = Factories.create_team(organization=organization)
- Factories.create_team_membership(team=team, user=owner)
- return team
- @pytest.fixture
- def project(organization, team):
- return Factories.create_project(organization=organization, teams=[team])
- @pytest.fixture
- def ios_profile():
- return load_profile("valid_ios_profile.json")
- @pytest.fixture
- def android_profile():
- return load_profile("valid_android_profile.json")
- @pytest.fixture
- def sample_v1_profile():
- return json.loads(
- """{
- "event_id": "41fed0925670468bb0457f61a74688ec",
- "version": "1",
- "os": {
- "name": "iOS",
- "version": "16.0",
- "build_number": "19H253"
- },
- "device": {
- "architecture": "arm64e",
- "is_emulator": false,
- "locale": "en_US",
- "manufacturer": "Apple",
- "model": "iPhone14,3"
- },
- "timestamp": "2022-09-01T09:45:00.000Z",
- "profile": {
- "samples": [
- {
- "stack_id": 0,
- "thread_id": "1",
- "queue_address": "0x0000000102adc700",
- "elapsed_since_start_ns": "10500500"
- },
- {
- "stack_id": 1,
- "thread_id": "1",
- "queue_address": "0x0000000102adc700",
- "elapsed_since_start_ns": "20500500"
- },
- {
- "stack_id": 0,
- "thread_id": "1",
- "queue_address": "0x0000000102adc700",
- "elapsed_since_start_ns": "30500500"
- },
- {
- "stack_id": 1,
- "thread_id": "1",
- "queue_address": "0x0000000102adc700",
- "elapsed_since_start_ns": "35500500"
- }
- ],
- "stacks": [[0], [1]],
- "frames": [
- {"instruction_addr": "0xa722447ffffffffc"},
- {"instruction_addr": "0x442e4b81f5031e58"}
- ],
- "thread_metadata": {
- "1": {"priority": 31},
- "2": {}
- },
- "queue_metadata": {
- "0x0000000102adc700": {"label": "com.apple.main-thread"},
- "0x000000016d8fb180": {"label": "com.apple.network.connections"}
- }
- },
- "release": "0.1 (199)",
- "platform": "cocoa",
- "debug_meta": {
- "images": [
- {
- "debug_id": "32420279-25E2-34E6-8BC7-8A006A8F2425",
- "image_addr": "0x000000010258c000",
- "code_file": "/private/var/containers/Bundle/Application/C3511752-DD67-4FE8-9DA2-ACE18ADFAA61/TrendingMovies.app/TrendingMovies",
- "type": "macho",
- "image_size": 1720320,
- "image_vmaddr": "0x0000000100000000"
- }
- ]
- },
- "transaction": {
- "name": "example_ios_movies_sources.MoviesViewController",
- "trace_id": "4b25bc58f14243d8b208d1e22a054164",
- "id": "30976f2ddbe04ac9b6bffe6e35d4710c",
- "active_thread_id": "259",
- "relative_start_ns": "500500",
- "relative_end_ns": "50500500"
- }
- }"""
- )
- @pytest.fixture
- def sample_v1_profile_without_transaction_timestamps(sample_v1_profile):
- for key in {"relative_start_ns", "relative_end_ns"}:
- del sample_v1_profile["transaction"][key]
- return sample_v1_profile
- @pytest.fixture
- def sample_v2_profile():
- return json.loads(
- """{
- "event_id": "41fed0925670468bb0457f61a74688ec",
- "version": "2",
- "profile": {
- "samples": [
- {
- "stack_id": 0,
- "thread_id": "1",
- "timestamp": 1710958503.629
- },
- {
- "stack_id": 1,
- "thread_id": "1",
- "timestamp": 1710958504.629
- },
- {
- "stack_id": 0,
- "thread_id": "1",
- "timestamp": 1710958505.629
- },
- {
- "stack_id": 1,
- "thread_id": "1",
- "timestamp": 1710958506.629
- }
- ],
- "stacks": [[0], [1]],
- "frames": [
- {"instruction_addr": "0xa722447ffffffffc"},
- {"instruction_addr": "0x442e4b81f5031e58"}
- ],
- "thread_metadata": {
- "1": {"priority": 31},
- "2": {}
- }
- },
- "release": "0.1 (199)",
- "platform": "cocoa",
- "debug_meta": {
- "images": [
- {
- "debug_id": "32420279-25E2-34E6-8BC7-8A006A8F2425",
- "image_addr": "0x000000010258c000",
- "code_file": "/private/var/containers/Bundle/Application/C3511752-DD67-4FE8-9DA2-ACE18ADFAA61/TrendingMovies.app/TrendingMovies",
- "type": "macho",
- "image_size": 1720320,
- "image_vmaddr": "0x0000000100000000"
- }
- ]
- }
- }"""
- )
- @pytest.fixture
- def proguard_file_basic(project):
- return load_proguard(project, PROGUARD_UUID, PROGUARD_SOURCE)
- @pytest.fixture
- def proguard_file_inline(project):
- return load_proguard(project, PROGUARD_INLINE_UUID, PROGUARD_INLINE_SOURCE)
- @pytest.fixture
- def proguard_file_bug(project):
- return load_proguard(project, PROGUARD_BUG_UUID, PROGUARD_BUG_SOURCE)
- @django_db_all
- def test_normalize_ios_profile(organization, ios_profile):
- _normalize(profile=ios_profile, organization=organization)
- for k in ["device_os_build_number", "device_classification"]:
- assert k in ios_profile
- @django_db_all
- def test_normalize_android_profile(organization, android_profile):
- _normalize(profile=android_profile, organization=organization)
- for k in ["android_api_level", "device_classification"]:
- assert k in android_profile
- assert isinstance(android_profile["android_api_level"], int)
- @django_db_all
- def test_basic_deobfuscation(project, proguard_file_basic, android_profile):
- android_profile.update(
- {
- "build_id": PROGUARD_UUID,
- "project_id": project.id,
- "profile": {
- "methods": [
- {
- "abs_path": None,
- "class_name": "org.a.b.g$a",
- "name": "a",
- "signature": "()V",
- "source_file": None,
- "source_line": 67,
- },
- {
- "abs_path": None,
- "class_name": "org.a.b.g$a",
- "name": "a",
- "signature": "()V",
- "source_file": None,
- "source_line": 69,
- },
- ],
- },
- }
- )
- _deobfuscate_locally(android_profile, project, PROGUARD_UUID)
- frames = android_profile["profile"]["methods"]
- assert frames[0]["name"] == "getClassContext"
- assert frames[0]["class_name"] == "org.slf4j.helpers.Util$ClassContextSecurityManager"
- assert frames[1]["name"] == "getExtraClassContext"
- assert frames[1]["class_name"] == "org.slf4j.helpers.Util$ClassContextSecurityManager"
- @django_db_all
- def test_inline_deobfuscation(project, proguard_file_inline, android_profile):
- android_profile.update(
- {
- "build_id": PROGUARD_INLINE_UUID,
- "project_id": project.id,
- "profile": {
- "methods": [
- {
- "abs_path": None,
- "class_name": "e.a.c.a",
- "name": "onClick",
- "signature": "()V",
- "source_file": None,
- "source_line": 2,
- },
- {
- "abs_path": None,
- "class_name": "io.sentry.sample.MainActivity",
- "name": "t",
- "signature": "()V",
- "source_file": "MainActivity.java",
- "source_line": 1,
- },
- ],
- },
- }
- )
- project = Project.objects.get_from_cache(id=android_profile["project_id"])
- _deobfuscate_locally(android_profile, project, PROGUARD_INLINE_UUID)
- frames = android_profile["profile"]["methods"]
- assert sum(len(f.get("inline_frames", [])) for f in frames) == 3
- assert frames[0]["name"] == "onClick"
- assert frames[0]["class_name"] == "io.sentry.sample.-$$Lambda$r3Avcbztes2hicEObh02jjhQqd4"
- assert frames[1]["inline_frames"][0]["name"] == "onClickHandler"
- assert frames[1]["inline_frames"][0]["source_line"] == 40
- assert frames[1]["inline_frames"][0]["source_file"] == "MainActivity.java"
- assert frames[1]["inline_frames"][0]["class_name"] == "io.sentry.sample.MainActivity"
- assert frames[1]["inline_frames"][0]["signature"] == "()"
- assert frames[1]["inline_frames"][1]["name"] == "foo"
- assert frames[1]["inline_frames"][1]["source_line"] == 44
- assert frames[1]["inline_frames"][2]["source_file"] == "MainActivity.java"
- assert frames[1]["inline_frames"][2]["class_name"] == "io.sentry.sample.MainActivity"
- assert frames[1]["inline_frames"][2]["name"] == "bar"
- assert frames[1]["inline_frames"][2]["source_line"] == 54
- @django_db_all
- def test_error_on_resolving(project, proguard_file_bug, android_profile):
- android_profile.update(
- {
- "build_id": PROGUARD_BUG_UUID,
- "project_id": project.id,
- "profile": {
- "methods": [
- {
- "name": "a",
- "abs_path": None,
- "class_name": "org.a.b.g$a",
- "source_file": None,
- "source_line": 67,
- },
- {
- "name": "a",
- "abs_path": None,
- "class_name": "org.a.b.g$a",
- "source_file": None,
- "source_line": 69,
- },
- ],
- },
- }
- )
- project = Project.objects.get_from_cache(id=android_profile["project_id"])
- obfuscated_frames = android_profile["profile"]["methods"].copy()
- _deobfuscate(android_profile, project)
- assert android_profile["profile"]["methods"] == obfuscated_frames
- def test_process_symbolicator_results_for_sample():
- profile: dict[str, Any] = {
- "version": 1,
- "platform": "rust",
- "profile": {
- "frames": [
- {
- "instruction_addr": "0x55bd050e168d",
- "lang": "rust",
- "sym_addr": "0x55bd050e1590",
- },
- {
- "instruction_addr": "0x89bf050e178a",
- "lang": "rust",
- "sym_addr": "0x95bc050e2530",
- },
- {
- "instruction_addr": "0x88ad050d167e",
- "lang": "rust",
- "sym_addr": "0x29cd050a1642",
- },
- ],
- "samples": [
- {"stack_id": 0},
- # a second sample with the same stack id, the stack should
- # not be processed a second time
- {"stack_id": 0},
- ],
- "stacks": [
- [0, 1, 2],
- ],
- },
- }
- # returned from symbolicator
- stacktraces = [
- {
- "frames": [
- {
- "instruction_addr": "0x72ba053e168c",
- "lang": "rust",
- "function": "C_inline_1",
- "original_index": 0,
- },
- {
- "instruction_addr": "0x55bd050e168d",
- "lang": "rust",
- "function": "C",
- "sym_addr": "0x55bd050e1590",
- "original_index": 0,
- },
- {
- "instruction_addr": "0x89bf050e178a",
- "lang": "rust",
- "function": "B",
- "sym_addr": "0x95bc050e2530",
- "original_index": 1,
- },
- {
- "instruction_addr": "0x68fd050d127b",
- "lang": "rust",
- "function": "A_inline_1",
- "original_index": 2,
- },
- {
- "instruction_addr": "0x29ce061d168a",
- "lang": "rust",
- "function": "A_inline_2",
- "original_index": 2,
- },
- {
- "instruction_addr": "0x88ad050d167e",
- "lang": "rust",
- "function": "A",
- "sym_addr": "0x29cd050a1642",
- "original_index": 2,
- },
- ],
- },
- ]
- _process_symbolicator_results_for_sample(
- profile, stacktraces, set(range(len(profile["profile"]["frames"]))), profile["platform"]
- )
- assert profile["profile"]["stacks"] == [[0, 1, 2, 3, 4, 5]]
- def test_process_symbolicator_results_for_sample_js():
- profile: dict[str, Any] = {
- "version": 1,
- "platform": "javascript",
- "profile": {
- "frames": [
- {
- "function": "functionA",
- "abs_path": "/root/functionA.js",
- },
- {
- "function": "functionB",
- "abs_path": "/root/functionB.js",
- },
- {
- "function": "functionC",
- "abs_path": "/root/functionC.js",
- },
- # frame not valid for symbolication
- {
- "function": "functionD",
- },
- ],
- "samples": [
- {"stack_id": 0},
- # a second sample with the same stack id, the stack should
- # not be processed a second time
- {"stack_id": 0},
- ],
- "stacks": [
- [0, 1, 2, 3],
- ],
- },
- }
- # returned from symbolicator
- stacktraces = [
- {
- "frames": [
- {
- "function": "functionA",
- "abs_path": "/root/functionA.js",
- "original_index": 0,
- },
- {
- "function": "functionB",
- "abs_path": "/root/functionB.js",
- "original_index": 1,
- },
- {
- "function": "functionC",
- "abs_path": "/root/functionC.js",
- "original_index": 2,
- },
- ],
- },
- ]
- frames_sent = [
- idx
- for idx, frame in enumerate(profile["profile"]["frames"])
- if is_valid_javascript_frame(frame, profile)
- ]
- _process_symbolicator_results_for_sample(
- profile, stacktraces, set(frames_sent), profile["platform"]
- )
- assert profile["profile"]["stacks"] == [[0, 1, 2, 3]]
- @django_db_all
- def test_decode_signature(project, android_profile):
- android_profile.update(
- {
- "project_id": project.id,
- "profile": {
- "methods": [
- {
- "abs_path": None,
- "class_name": "org.a.b.g$a",
- "name": "a",
- "signature": "()V",
- "source_file": None,
- "source_line": 67,
- },
- {
- "abs_path": None,
- "class_name": "org.a.b.g$a",
- "name": "a",
- "signature": "()Z",
- "source_file": None,
- "source_line": 69,
- },
- ],
- },
- }
- )
- _deobfuscate(android_profile, project)
- frames = android_profile["profile"]["methods"]
- assert frames[0]["signature"] == "()"
- assert frames[1]["signature"] == "(): boolean"
- @django_db_all
- @pytest.mark.parametrize(
- "profile, duration_ms",
- [
- ("sample_v1_profile", 50),
- ("sample_v2_profile", 3000),
- ("android_profile", 2020),
- ("sample_v1_profile_without_transaction_timestamps", 25),
- ],
- )
- def test_calculate_profile_duration(profile, duration_ms, request):
- assert _calculate_profile_duration_ms(request.getfixturevalue(profile)) == duration_ms
- @pytest.mark.django_db(transaction=True)
- class DeobfuscationViaSymbolicator(TransactionTestCase):
- @pytest.fixture(autouse=True)
- def initialize(self, set_sentry_option, live_server):
- with set_sentry_option("system.url-prefix", live_server.url):
- # Run test case
- yield
- def upload_proguard_mapping(self, uuid, mapping_file_content):
- url = reverse(
- "sentry-api-0-dsym-files",
- kwargs={
- "organization_id_or_slug": self.project.organization.slug,
- "project_id_or_slug": self.project.slug,
- },
- )
- self.login_as(user=self.user)
- out = BytesIO()
- f = zipfile.ZipFile(out, "w")
- f.writestr("proguard/%s.txt" % uuid, mapping_file_content)
- f.writestr("ignored-file.txt", b"This is just some stuff")
- 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.json()) == 1
- @requires_symbolicator
- @pytest.mark.symbolicator
- def test_basic_resolving(self):
- self.upload_proguard_mapping(PROGUARD_UUID, PROGUARD_SOURCE)
- android_profile = load_profile("valid_android_profile.json")
- android_profile.update(
- {
- "project_id": self.project.id,
- "build_id": PROGUARD_UUID,
- "event_id": android_profile["profile_id"],
- "profile": {
- "methods": [
- {
- "class_name": "org.a.b.g$a",
- "name": "a",
- "signature": "()V",
- "source_file": "Something.java",
- "source_line": 67,
- },
- {
- "class_name": "org.a.b.g$a",
- "name": "a",
- "signature": "()Z",
- "source_file": "Else.java",
- "source_line": 69,
- },
- ],
- },
- }
- )
- _deobfuscate_using_symbolicator(
- self.project,
- android_profile,
- PROGUARD_UUID,
- )
- assert android_profile["profile"]["methods"] == [
- {
- "data": {"deobfuscation_status": "deobfuscated"},
- "name": "getClassContext",
- "class_name": "org.slf4j.helpers.Util$ClassContextSecurityManager",
- "signature": "()",
- "source_file": "Something.java",
- "source_line": 67,
- },
- {
- "data": {"deobfuscation_status": "deobfuscated"},
- "name": "getExtraClassContext",
- "class_name": "org.slf4j.helpers.Util$ClassContextSecurityManager",
- "signature": "(): boolean",
- "source_file": "Else.java",
- "source_line": 69,
- },
- ]
- @requires_symbolicator
- @pytest.mark.symbolicator
- def test_inline_resolving(self):
- self.upload_proguard_mapping(PROGUARD_INLINE_UUID, PROGUARD_INLINE_SOURCE)
- android_profile = load_profile("valid_android_profile.json")
- android_profile.update(
- {
- "project_id": self.project.id,
- "build_id": PROGUARD_INLINE_UUID,
- "event_id": android_profile["profile_id"],
- "profile": {
- "methods": [
- {
- "class_name": "e.a.c.a",
- "name": "onClick",
- "signature": "()V",
- "source_file": None,
- "source_line": 2,
- },
- {
- "class_name": "io.sentry.sample.MainActivity",
- "name": "t",
- "signature": "()V",
- "source_file": "MainActivity.java",
- "source_line": 1,
- },
- ],
- },
- }
- )
- _deobfuscate_using_symbolicator(
- self.project,
- android_profile,
- PROGUARD_INLINE_UUID,
- )
- assert android_profile["profile"]["methods"] == [
- {
- "class_name": "io.sentry.sample.-$$Lambda$r3Avcbztes2hicEObh02jjhQqd4",
- "data": {
- "deobfuscation_status": "deobfuscated",
- },
- "name": "onClick",
- "signature": "()",
- "source_file": None,
- "source_line": 2,
- },
- {
- "class_name": "io.sentry.sample.MainActivity",
- "data": {
- "deobfuscation_status": "deobfuscated",
- },
- "inline_frames": [
- {
- "class_name": "io.sentry.sample.MainActivity",
- "data": {
- "deobfuscation_status": "deobfuscated",
- },
- "name": "onClickHandler",
- "signature": "()",
- "source_file": "MainActivity.java",
- "source_line": 40,
- },
- {
- "class_name": "io.sentry.sample.MainActivity",
- "data": {
- "deobfuscation_status": "deobfuscated",
- },
- "name": "foo",
- "signature": "()",
- "source_file": "MainActivity.java",
- "source_line": 44,
- },
- {
- "class_name": "io.sentry.sample.MainActivity",
- "data": {
- "deobfuscation_status": "deobfuscated",
- },
- "name": "bar",
- "signature": "()",
- "source_file": "MainActivity.java",
- "source_line": 54,
- },
- ],
- "name": "onClickHandler",
- "signature": "()",
- "source_file": "MainActivity.java",
- "source_line": 40,
- },
- ]
- @requires_symbolicator
- @pytest.mark.symbolicator
- def test_js_symbolication_set_symbolicated_field(self):
- release = Release.objects.create(
- organization_id=self.project.organization_id, version="nodeprof123"
- )
- release.add_project(self.project)
- for file in ["embedded.js", "embedded.js.map"]:
- with open(get_fixture_path(f"profiles/{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,
- )
- js_profile = load_profile("valid_js_profile.json")
- js_profile.update(
- {
- "project_id": self.project.id,
- "event_id": js_profile["profile_id"],
- "release": release.version,
- "debug_meta": {"images": []},
- }
- )
- _symbolicate_profile(js_profile, self.project)
- assert js_profile["profile"]["frames"][0].get("data", {}).get("symbolicated", False)
- def test_set_frames_platform_sample():
- js_prof: Profile = {
- "version": "1",
- "platform": "javascript",
- "profile": {
- "frames": [
- {"function": "a"},
- {"function": "b", "platform": "cocoa"},
- {"function": "c"},
- ]
- },
- }
- _set_frames_platform(js_prof)
- platforms = [f["platform"] for f in js_prof["profile"]["frames"]]
- assert platforms == ["javascript", "cocoa", "javascript"]
- def test_set_frames_platform_android():
- android_prof: Profile = {
- "platform": "android",
- "profile": {
- "methods": [
- {"name": "a"},
- {"name": "b"},
- ]
- },
- }
- _set_frames_platform(android_prof)
- platforms = [m["platform"] for m in android_prof["profile"]["methods"]]
- assert platforms == ["android", "android"]
- @django_db_all
- def test_get_metrics_dsn(default_project):
- key1 = ProjectKey.objects.create(project=default_project, use_case=UseCase.PROFILING.value)
- ProjectKey.objects.create(project_id=default_project.id, use_case=UseCase.PROFILING.value)
- assert get_metrics_dsn(default_project.id) == key1.get_dsn(public=True)
|