test_plugin.py 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497
  1. import zipfile
  2. from io import BytesIO
  3. from uuid import uuid4
  4. import pytest
  5. from django.core.files.uploadedfile import SimpleUploadedFile
  6. from django.urls import reverse
  7. from sentry.models.debugfile import ProjectDebugFile
  8. from sentry.models.files.file import File
  9. from sentry.testutils.cases import TransactionTestCase
  10. from sentry.testutils.helpers.datetime import before_now, iso_format
  11. from sentry.testutils.relay import RelayStoreHelper
  12. from sentry.utils import json
  13. PROGUARD_UUID = "6dc7fdb0-d2fb-4c8e-9d6b-bb1aa98929b1"
  14. PROGUARD_SOURCE = b"""\
  15. org.slf4j.helpers.Util$ClassContextSecurityManager -> org.a.b.g$a:
  16. 65:65:void <init>() -> <init>
  17. 67:67:java.lang.Class[] getClassContext() -> a
  18. 69:69:java.lang.Class[] getExtraClassContext() -> a
  19. 68:68:java.lang.Class[] getContext() -> a
  20. 65:65:void <init>(org.slf4j.helpers.Util$1) -> <init>
  21. org.slf4j.helpers.Util$ClassContext -> org.a.b.g$b:
  22. 65:65:void <init>() -> <init>
  23. """
  24. PROGUARD_INLINE_UUID = "d748e578-b3d1-5be5-b0e5-a42e8c9bf8e0"
  25. PROGUARD_INLINE_SOURCE = b"""\
  26. # compiler: R8
  27. # compiler_version: 2.0.74
  28. # min_api: 16
  29. # pg_map_id: 5b46fdc
  30. # common_typos_disable
  31. $r8$backportedMethods$utility$Objects$2$equals -> a:
  32. boolean equals(java.lang.Object,java.lang.Object) -> a
  33. $r8$twr$utility -> b:
  34. void $closeResource(java.lang.Throwable,java.lang.Object) -> a
  35. android.support.v4.app.RemoteActionCompatParcelizer -> android.support.v4.app.RemoteActionCompatParcelizer:
  36. 1:1:void <init>():11:11 -> <init>
  37. io.sentry.sample.-$$Lambda$r3Avcbztes2hicEObh02jjhQqd4 -> e.a.c.a:
  38. io.sentry.sample.MainActivity f$0 -> b
  39. io.sentry.sample.MainActivity -> io.sentry.sample.MainActivity:
  40. 1:1:void <init>():15:15 -> <init>
  41. 1:1:boolean onCreateOptionsMenu(android.view.Menu):60:60 -> onCreateOptionsMenu
  42. 1:1:boolean onOptionsItemSelected(android.view.MenuItem):69:69 -> onOptionsItemSelected
  43. 2:2:boolean onOptionsItemSelected(android.view.MenuItem):76:76 -> onOptionsItemSelected
  44. 1:1:void bar():54:54 -> t
  45. 1:1:void foo():44 -> t
  46. 1:1:void onClickHandler(android.view.View):40 -> t
  47. """
  48. PROGUARD_BUG_UUID = "071207ac-b491-4a74-957c-2c94fd9594f2"
  49. PROGUARD_BUG_SOURCE = b"x"
  50. JVM_DEBUG_ID = "6dc7fdb0-d2fb-4c8e-9d6b-bb1aa98929b1"
  51. JVM_SOURCE = b"""\
  52. package io.sentry.samples
  53. import android.content.Intent
  54. import android.os.Bundle
  55. import androidx.activity.ComponentActivity
  56. class MainActivity : ComponentActivity() {
  57. override fun onCreate(savedInstanceState: Bundle?) {
  58. super.onCreate(savedInstanceState)
  59. setContentView(R.layout.activity_main)
  60. InnerClass().whoops()
  61. val list = findViewById<RecyclerView>(R.id.list)
  62. list.layoutManager = LinearLayoutManager(this)
  63. list.adapter = TrackAdapter()
  64. }
  65. class InnerClass {
  66. fun whoops() {
  67. AnotherInnerClass().whoops2()
  68. }
  69. }
  70. class AnotherInnerClass {
  71. fun whoops2() {
  72. AdditionalInnerClass().whoops3()
  73. }
  74. }
  75. class AdditionalInnerClass {
  76. fun whoops3() {
  77. OneMoreInnerClass().whoops4()
  78. }
  79. }
  80. class OneMoreInnerClass {
  81. fun whoops4() {
  82. throw RuntimeException("whoops")
  83. }
  84. }
  85. }
  86. """
  87. PROGUARD_SOURCE_LOOKUP_UUID = "05d96b1c-1786-477c-8615-d3cf83e027c7"
  88. PROGUARD_SOURCE_LOOKUP_SOURCE = b"""\
  89. io.sentry.samples.instrumentation.ui.EditActivity -> io.sentry.samples.instrumentation.ui.EditActivity:
  90. # {"id":"sourceFile","fileName":"EditActivity.kt"}
  91. int $r8$clinit -> a
  92. 0:65535:void <init>():15:15 -> <init>
  93. 1:6:void onCreate(android.os.Bundle):18:18 -> onCreate
  94. 7:12:void onCreate(android.os.Bundle):19:19 -> onCreate
  95. 13:22:void onCreate(android.os.Bundle):21:21 -> onCreate
  96. 23:32:void onCreate(android.os.Bundle):22:22 -> onCreate
  97. 33:42:void onCreate(android.os.Bundle):23:23 -> onCreate
  98. 43:49:void onCreate(android.os.Bundle):24:24 -> onCreate
  99. 50:71:void onCreate(android.os.Bundle):26:26 -> onCreate
  100. 72:73:java.lang.String io.sentry.samples.instrumentation.data.Track.getName():46:46 -> onCreate
  101. 72:73:void onCreate(android.os.Bundle):28 -> onCreate
  102. 74:76:void onCreate(android.os.Bundle):28:28 -> onCreate
  103. 77:78:java.lang.String io.sentry.samples.instrumentation.data.Track.getComposer():48:48 -> onCreate
  104. 77:78:void onCreate(android.os.Bundle):29 -> onCreate
  105. 79:81:void onCreate(android.os.Bundle):29:29 -> onCreate
  106. 82:83:long io.sentry.samples.instrumentation.data.Track.getMillis():51:51 -> onCreate
  107. 82:83:void onCreate(android.os.Bundle):30 -> onCreate
  108. 84:90:void onCreate(android.os.Bundle):30:30 -> onCreate
  109. 91:92:float io.sentry.samples.instrumentation.data.Track.getPrice():53:53 -> onCreate
  110. 91:92:void onCreate(android.os.Bundle):31 -> onCreate
  111. 93:102:void onCreate(android.os.Bundle):31:31 -> onCreate
  112. 103:119:void onCreate(android.os.Bundle):34:34 -> onCreate
  113. io.sentry.samples.instrumentation.ui.EditActivity$$ExternalSyntheticLambda0 -> io.sentry.samples.instrumentation.ui.g:
  114. # {"id":"sourceFile","fileName":"R8$$SyntheticClass"}
  115. # {"id":"com.android.tools.r8.synthesized"}
  116. android.widget.EditText io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.f$4 -> e
  117. android.widget.EditText io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.f$3 -> d
  118. android.widget.EditText io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.f$2 -> c
  119. io.sentry.samples.instrumentation.data.Track io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.f$0 -> a
  120. android.widget.EditText io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.f$1 -> b
  121. io.sentry.samples.instrumentation.ui.EditActivity io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.f$5 -> f
  122. void io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.<init>(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity) -> <init>
  123. # {"id":"com.android.tools.r8.synthesized"}
  124. 19:21:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):0:0 -> onMenuItemClick
  125. 19:21:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  126. # {"id":"com.android.tools.r8.synthesized"}
  127. 22:35:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):35:35 -> onMenuItemClick
  128. 22:35:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  129. # {"id":"com.android.tools.r8.synthesized"}
  130. 36:44:void io.sentry.samples.instrumentation.ui.AnotherClassInSameFile$AnotherInnerClass.helloOtherInner():26:26 -> onMenuItemClick
  131. 36:44:void io.sentry.samples.instrumentation.ui.AnotherClassInSameFile.otherFun():21 -> onMenuItemClick
  132. 36:44:void io.sentry.samples.instrumentation.ui.AnotherClassInSameFile.helloOther():17 -> onMenuItemClick
  133. 36:44:void io.sentry.samples.instrumentation.ui.SomeService$InnerClassOfSomeService.helloInner():10 -> onMenuItemClick
  134. 36:44:void io.sentry.samples.instrumentation.ui.SomeService.helloThere():5 -> onMenuItemClick
  135. 36:44:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):37 -> onMenuItemClick
  136. 36:44:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  137. # {"id":"com.android.tools.r8.synthesized"}
  138. 45:58:io.sentry.protocol.SentryId io.sentry.Sentry.captureException(java.lang.Throwable):433:433 -> onMenuItemClick
  139. 45:58:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):39 -> onMenuItemClick
  140. 45:58:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  141. # {"id":"com.android.tools.r8.synthesized"}
  142. 59:68:io.sentry.ITransaction io.sentry.Sentry.startTransaction(java.lang.String,java.lang.String,boolean):697:697 -> onMenuItemClick
  143. 59:68:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):42 -> onMenuItemClick
  144. 59:68:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  145. # {"id":"com.android.tools.r8.synthesized"}
  146. 69:71:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):42:42 -> onMenuItemClick
  147. 69:71:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  148. # {"id":"com.android.tools.r8.synthesized"}
  149. 72:79:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):48:48 -> onMenuItemClick
  150. 72:79:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  151. # {"id":"com.android.tools.r8.synthesized"}
  152. 80:87:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):49:49 -> onMenuItemClick
  153. 80:87:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  154. # {"id":"com.android.tools.r8.synthesized"}
  155. 88:95:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):50:50 -> onMenuItemClick
  156. 88:95:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  157. # {"id":"com.android.tools.r8.synthesized"}
  158. 96:103:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):51:51 -> onMenuItemClick
  159. 96:103:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  160. # {"id":"com.android.tools.r8.synthesized"}
  161. 104:125:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):52:52 -> onMenuItemClick
  162. 104:125:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  163. # {"id":"com.android.tools.r8.synthesized"}
  164. 126:142:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):53:53 -> onMenuItemClick
  165. 126:142:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  166. # {"id":"com.android.tools.r8.synthesized"}
  167. 143:164:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):54:54 -> onMenuItemClick
  168. 143:164:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  169. # {"id":"com.android.tools.r8.synthesized"}
  170. 165:175:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):64:64 -> onMenuItemClick
  171. 165:175:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  172. # {"id":"com.android.tools.r8.synthesized"}
  173. 176:187:void io.sentry.samples.instrumentation.ui.EditActivity.addNewTrack(java.lang.String,java.lang.String,long,float):84:84 -> onMenuItemClick
  174. 176:187:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):64 -> onMenuItemClick
  175. 176:187:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  176. # {"id":"com.android.tools.r8.synthesized"}
  177. 188:190:void io.sentry.samples.instrumentation.data.Track.<init>(long,java.lang.String,java.lang.Long,java.lang.String,java.lang.Long,java.lang.Long,long,java.lang.Long,float,int,kotlin.jvm.internal.DefaultConstructorMarker):43:43 -> onMenuItemClick
  178. 188:190:void io.sentry.samples.instrumentation.ui.EditActivity.addNewTrack(java.lang.String,java.lang.String,long,float):84 -> onMenuItemClick
  179. 188:190:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):64 -> onMenuItemClick
  180. 188:190:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  181. # {"id":"com.android.tools.r8.synthesized"}
  182. 191:198:void io.sentry.samples.instrumentation.ui.EditActivity.addNewTrack(java.lang.String,java.lang.String,long,float):94:94 -> onMenuItemClick
  183. 191:198:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):64 -> onMenuItemClick
  184. 191:198:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  185. # {"id":"com.android.tools.r8.synthesized"}
  186. 199:211:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):66:66 -> onMenuItemClick
  187. 199:211:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  188. # {"id":"com.android.tools.r8.synthesized"}
  189. 212:227:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):67:67 -> onMenuItemClick
  190. 212:227:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  191. # {"id":"com.android.tools.r8.synthesized"}
  192. 228:238:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):69:69 -> onMenuItemClick
  193. 228:238:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  194. # {"id":"com.android.tools.r8.synthesized"}
  195. 239:250:io.sentry.samples.instrumentation.data.Track io.sentry.samples.instrumentation.data.Track.copy$default(io.sentry.samples.instrumentation.data.Track,long,java.lang.String,java.lang.Long,java.lang.String,java.lang.Long,java.lang.Long,long,java.lang.Long,float,int,java.lang.Object):0:0 -> onMenuItemClick
  196. 239:250:void io.sentry.samples.instrumentation.ui.EditActivity.update(io.sentry.samples.instrumentation.data.Track,java.lang.String,java.lang.String,long,float):100 -> onMenuItemClick
  197. 239:250:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):69 -> onMenuItemClick
  198. 239:250:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  199. # {"id":"com.android.tools.r8.synthesized"}
  200. 251:265:io.sentry.samples.instrumentation.data.Track io.sentry.samples.instrumentation.data.Track.copy(long,java.lang.String,java.lang.Long,java.lang.String,java.lang.Long,java.lang.Long,long,java.lang.Long,float):0:0 -> onMenuItemClick
  201. 251:265:io.sentry.samples.instrumentation.data.Track io.sentry.samples.instrumentation.data.Track.copy$default(io.sentry.samples.instrumentation.data.Track,long,java.lang.String,java.lang.Long,java.lang.String,java.lang.Long,java.lang.Long,long,java.lang.Long,float,int,java.lang.Object):0 -> onMenuItemClick
  202. 251:265:void io.sentry.samples.instrumentation.ui.EditActivity.update(io.sentry.samples.instrumentation.data.Track,java.lang.String,java.lang.String,long,float):100 -> onMenuItemClick
  203. 251:265:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):69 -> onMenuItemClick
  204. 251:265:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  205. # {"id":"com.android.tools.r8.synthesized"}
  206. 266:273:void io.sentry.samples.instrumentation.ui.EditActivity.update(io.sentry.samples.instrumentation.data.Track,java.lang.String,java.lang.String,long,float):106:106 -> onMenuItemClick
  207. 266:273:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):69 -> onMenuItemClick
  208. 266:273:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  209. # {"id":"com.android.tools.r8.synthesized"}
  210. 274:286:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):71:71 -> onMenuItemClick
  211. 274:286:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  212. # {"id":"com.android.tools.r8.synthesized"}
  213. 287:301:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):72:72 -> onMenuItemClick
  214. 287:301:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  215. # {"id":"com.android.tools.r8.synthesized"}
  216. 302:306:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):74:74 -> onMenuItemClick
  217. 302:306:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  218. # {"id":"com.android.tools.r8.synthesized"}
  219. 307:312:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):75:75 -> onMenuItemClick
  220. 307:312:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  221. # {"id":"com.android.tools.r8.synthesized"}
  222. 313:316:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):56:56 -> onMenuItemClick
  223. 313:316:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  224. # {"id":"com.android.tools.r8.synthesized"}
  225. 317:320:boolean io.sentry.samples.instrumentation.ui.EditActivity.onCreate$lambda-1(io.sentry.samples.instrumentation.data.Track,android.widget.EditText,android.widget.EditText,android.widget.EditText,android.widget.EditText,io.sentry.samples.instrumentation.ui.EditActivity,android.view.MenuItem):61:61 -> onMenuItemClick
  226. 317:320:boolean io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0.onMenuItemClick(android.view.MenuItem):0 -> onMenuItemClick
  227. # {"id":"com.android.tools.r8.synthesized"}
  228. """
  229. EDIT_ACTIVITY_SOURCE = b"""\
  230. package io.sentry.samples.instrumentation.ui
  231. import android.os.Bundle
  232. import android.widget.EditText
  233. import android.widget.Toast
  234. import androidx.activity.ComponentActivity
  235. import androidx.appcompat.widget.Toolbar
  236. import io.sentry.Sentry
  237. import io.sentry.SpanStatus
  238. import io.sentry.samples.instrumentation.R
  239. import io.sentry.samples.instrumentation.SampleApp
  240. import io.sentry.samples.instrumentation.data.Track
  241. import kotlinx.coroutines.runBlocking
  242. class EditActivity : ComponentActivity() {
  243. override fun onCreate(savedInstanceState: Bundle?) {
  244. super.onCreate(savedInstanceState)
  245. setContentView(R.layout.activity_edit)
  246. val nameInput = findViewById<EditText>(R.id.track_name)
  247. val composerInput = findViewById<EditText>(R.id.track_composer)
  248. val durationInput = findViewById<EditText>(R.id.track_duration)
  249. val unitPriceInput = findViewById<EditText>(R.id.track_unit_price)
  250. val originalTrack: Track? = intent.getSerializableExtra(TRACK_EXTRA_KEY) as? Track
  251. originalTrack?.run {
  252. nameInput.setText(name)
  253. composerInput.setText(composer)
  254. durationInput.setText(millis.toString())
  255. unitPriceInput.setText(price.toString())
  256. }
  257. findViewById<Toolbar>(R.id.toolbar).setOnMenuItemClickListener {
  258. if (it.itemId == R.id.action_save) {
  259. try {
  260. SomeService().helloThere()
  261. } catch (e: Exception) {
  262. Sentry.captureException(e)
  263. }
  264. val transaction = Sentry.startTransaction(
  265. "Track Interaction",
  266. if (originalTrack == null) "ui.action.add" else "ui.action.edit",
  267. true
  268. )
  269. val name = nameInput.text.toString()
  270. val composer = composerInput.text.toString()
  271. val duration = durationInput.text.toString()
  272. val unitPrice = unitPriceInput.text.toString()
  273. if (name.isEmpty() || composer.isEmpty() ||
  274. duration.isEmpty() || duration.toLongOrNull() == null ||
  275. unitPrice.isEmpty() || unitPrice.toFloatOrNull() == null
  276. ) {
  277. Toast.makeText(
  278. this,
  279. "Some of the inputs are empty or have wrong format " +
  280. "(duration/unitprice not a number)",
  281. Toast.LENGTH_LONG
  282. ).show()
  283. } else {
  284. if (originalTrack == null) {
  285. addNewTrack(name, composer, duration.toLong(), unitPrice.toFloat())
  286. val createCount = SampleApp.analytics.getInt("create_count", 0) + 1
  287. SampleApp.analytics.edit().putInt("create_count", createCount).apply()
  288. } else {
  289. originalTrack.update(name, composer, duration.toLong(), unitPrice.toFloat())
  290. val editCount = SampleApp.analytics.getInt("edit_count", 0) + 1
  291. SampleApp.analytics.edit().putInt("edit_count", editCount).apply()
  292. }
  293. transaction.finish(SpanStatus.OK)
  294. finish()
  295. }
  296. return@setOnMenuItemClickListener true
  297. }
  298. return@setOnMenuItemClickListener false
  299. }
  300. }
  301. private fun addNewTrack(name: String, composer: String, duration: Long, unitPrice: Float) {
  302. val newTrack = Track(
  303. name = name,
  304. albumId = null,
  305. composer = composer,
  306. mediaTypeId = null,
  307. genreId = null,
  308. millis = duration,
  309. bytes = null,
  310. price = unitPrice
  311. )
  312. runBlocking {
  313. SampleApp.database.tracksDao().insert(newTrack)
  314. }
  315. }
  316. private fun Track.update(name: String, composer: String, duration: Long, unitPrice: Float) {
  317. val updatedTrack = copy(
  318. name = name,
  319. composer = composer,
  320. millis = duration,
  321. price = unitPrice
  322. )
  323. runBlocking {
  324. SampleApp.database.tracksDao().update(updatedTrack)
  325. }
  326. }
  327. companion object {
  328. const val TRACK_EXTRA_KEY = "EditActivity.Track"
  329. }
  330. }
  331. """
  332. SOME_SERVICE_SOURCE = b"""\
  333. package io.sentry.samples.instrumentation.ui
  334. class SomeService {
  335. fun helloThere() {
  336. InnerClassOfSomeService().helloInner()
  337. }
  338. class InnerClassOfSomeService {
  339. fun helloInner() {
  340. AnotherClassInSameFile().helloOther()
  341. }
  342. }
  343. }
  344. class AnotherClassInSameFile {
  345. fun helloOther() {
  346. otherFun()
  347. }
  348. private fun otherFun() {
  349. AnotherInnerClass().helloOtherInner()
  350. }
  351. class AnotherInnerClass {
  352. fun helloOtherInner() {
  353. throw RuntimeException("thrown on purpose to test ProGuard Android source context")
  354. }
  355. }
  356. }
  357. """
  358. @pytest.mark.django_db(transaction=True)
  359. class BasicResolvingIntegrationTest(RelayStoreHelper, TransactionTestCase):
  360. def upload_proguard_mapping(self, uuid, mapping_file_content):
  361. url = reverse(
  362. "sentry-api-0-dsym-files",
  363. kwargs={
  364. "organization_slug": self.project.organization.slug,
  365. "project_slug": self.project.slug,
  366. },
  367. )
  368. self.login_as(user=self.user)
  369. out = BytesIO()
  370. f = zipfile.ZipFile(out, "w")
  371. f.writestr("proguard/%s.txt" % uuid, mapping_file_content)
  372. f.writestr("ignored-file.txt", b"This is just some stuff")
  373. f.close()
  374. response = self.client.post(
  375. url,
  376. {
  377. "file": SimpleUploadedFile(
  378. "symbols.zip", out.getvalue(), content_type="application/zip"
  379. )
  380. },
  381. format="multipart",
  382. )
  383. assert response.status_code == 201, response.content
  384. assert len(response.json()) == 1
  385. def test_basic_resolving(self):
  386. self.upload_proguard_mapping(PROGUARD_UUID, PROGUARD_SOURCE)
  387. event_data = {
  388. "user": {"ip_address": "31.172.207.97"},
  389. "extra": {},
  390. "project": self.project.id,
  391. "platform": "java",
  392. "debug_meta": {"images": [{"type": "proguard", "uuid": PROGUARD_UUID}]},
  393. "exception": {
  394. "values": [
  395. {
  396. "stacktrace": {
  397. "frames": [
  398. {
  399. "function": "a",
  400. "abs_path": None,
  401. "module": "org.a.b.g$a",
  402. "filename": None,
  403. "lineno": 67,
  404. },
  405. {
  406. "function": "a",
  407. "abs_path": None,
  408. "module": "org.a.b.g$a",
  409. "filename": None,
  410. "lineno": 69,
  411. },
  412. ]
  413. },
  414. "module": "org.a.b",
  415. "type": "g$a",
  416. "value": "Attempt to invoke virtual method 'org.a.b.g$a.a' on a null object reference",
  417. }
  418. ]
  419. },
  420. "timestamp": iso_format(before_now(seconds=1)),
  421. }
  422. event = self.post_and_retrieve_event(event_data)
  423. if not self.use_relay():
  424. # We measure the number of queries after an initial post,
  425. # because there are many queries polluting the array
  426. # before the actual "processing" happens (like, auth_user)
  427. with self.assertWriteQueries(
  428. {
  429. "nodestore_node": 2,
  430. "sentry_eventuser": 1,
  431. "sentry_groupedmessage": 1,
  432. "sentry_userreport": 1,
  433. }
  434. ):
  435. self.post_and_retrieve_event(event_data)
  436. exc = event.interfaces["exception"].values[0]
  437. bt = exc.stacktrace
  438. frames = bt.frames
  439. assert exc.type == "Util$ClassContextSecurityManager"
  440. assert (
  441. exc.value
  442. == "Attempt to invoke virtual method 'org.slf4j.helpers.Util$ClassContextSecurityManager.getExtraClassContext' on a null object reference"
  443. )
  444. assert exc.module == "org.slf4j.helpers"
  445. assert frames[0].function == "getClassContext"
  446. assert frames[0].module == "org.slf4j.helpers.Util$ClassContextSecurityManager"
  447. assert frames[1].function == "getExtraClassContext"
  448. assert frames[1].module == "org.slf4j.helpers.Util$ClassContextSecurityManager"
  449. assert event.culprit == (
  450. "org.slf4j.helpers.Util$ClassContextSecurityManager " "in getExtraClassContext"
  451. )
  452. def test_resolving_does_not_fail_when_no_value(self):
  453. self.upload_proguard_mapping(PROGUARD_UUID, PROGUARD_SOURCE)
  454. event_data = {
  455. "user": {"ip_address": "31.172.207.97"},
  456. "extra": {},
  457. "project": self.project.id,
  458. "platform": "java",
  459. "debug_meta": {"images": [{"type": "proguard", "uuid": PROGUARD_UUID}]},
  460. "exception": {
  461. "values": [
  462. {
  463. "stacktrace": {
  464. "frames": [
  465. {
  466. "function": "a",
  467. "abs_path": None,
  468. "module": "org.a.b.g$a",
  469. "filename": None,
  470. "lineno": 67,
  471. },
  472. {
  473. "function": "a",
  474. "abs_path": None,
  475. "module": "org.a.b.g$a",
  476. "filename": None,
  477. "lineno": 69,
  478. },
  479. ]
  480. },
  481. "module": "org.a.b",
  482. "type": "g$a",
  483. }
  484. ]
  485. },
  486. "timestamp": iso_format(before_now(seconds=1)),
  487. }
  488. event = self.post_and_retrieve_event(event_data)
  489. if not self.use_relay():
  490. # We measure the number of queries after an initial post,
  491. # because there are many queries polluting the array
  492. # before the actual "processing" happens (like, auth_user)
  493. with self.assertWriteQueries(
  494. {
  495. "nodestore_node": 2,
  496. "sentry_eventuser": 1,
  497. "sentry_groupedmessage": 1,
  498. "sentry_userreport": 1,
  499. }
  500. ):
  501. self.post_and_retrieve_event(event_data)
  502. metrics = event.data["_metrics"]
  503. assert not metrics.get("flag.processing.error")
  504. def test_resolving_does_not_fail_when_no_module_or_function(self):
  505. self.upload_proguard_mapping(PROGUARD_UUID, PROGUARD_SOURCE)
  506. event_data = {
  507. "user": {"ip_address": "31.172.207.97"},
  508. "extra": {},
  509. "project": self.project.id,
  510. "platform": "java",
  511. "debug_meta": {"images": [{"type": "proguard", "uuid": PROGUARD_UUID}]},
  512. "exception": {
  513. "values": [
  514. {
  515. "stacktrace": {
  516. "frames": [
  517. {
  518. "function": "a",
  519. "abs_path": None,
  520. "module": "org.a.b.g$a",
  521. "filename": None,
  522. "lineno": 67,
  523. },
  524. {
  525. "function": "a",
  526. "abs_path": None,
  527. "module": "org.a.b.g$a",
  528. "filename": None,
  529. "lineno": 69,
  530. },
  531. {
  532. "function": "__start_thread",
  533. "package": "/apex/com.android.art/lib64/libart.so",
  534. "lineno": 196,
  535. "in_app": False,
  536. },
  537. {
  538. "package": "/apex/com.android.art/lib64/libart.so",
  539. "lineno": 214,
  540. "in_app": False,
  541. },
  542. ]
  543. },
  544. "module": "org.a.b",
  545. "type": "g$a",
  546. "value": "Attempt to invoke virtual method 'org.a.b.g$a.a' on a null object reference",
  547. }
  548. ]
  549. },
  550. "timestamp": iso_format(before_now(seconds=1)),
  551. }
  552. event = self.post_and_retrieve_event(event_data)
  553. if not self.use_relay():
  554. # We measure the number of queries after an initial post,
  555. # because there are many queries polluting the array
  556. # before the actual "processing" happens (like, auth_user)
  557. with self.assertWriteQueries(
  558. {
  559. "nodestore_node": 2,
  560. "sentry_eventuser": 1,
  561. "sentry_groupedmessage": 1,
  562. "sentry_userreport": 1,
  563. }
  564. ):
  565. self.post_and_retrieve_event(event_data)
  566. metrics = event.data["_metrics"]
  567. assert not metrics.get("flag.processing.error")
  568. def test_sets_inapp_after_resolving(self):
  569. self.upload_proguard_mapping(PROGUARD_UUID, PROGUARD_SOURCE)
  570. version = "org.slf4j@1.2.3"
  571. env_name = "some_env"
  572. event = self.store_event(
  573. data={"release": version, "environment": env_name}, project_id=self.project.id
  574. )
  575. event_data = {
  576. "user": {"ip_address": "31.172.207.97"},
  577. "extra": {},
  578. "release": "org.slf4j@1.2.3",
  579. "project": self.project.id,
  580. "platform": "java",
  581. "debug_meta": {"images": [{"type": "proguard", "uuid": PROGUARD_UUID}]},
  582. "exception": {
  583. "values": [
  584. {
  585. "stacktrace": {
  586. "frames": [
  587. {
  588. "function": "a",
  589. "abs_path": None,
  590. "module": "org.a.b.g$a",
  591. "filename": None,
  592. "lineno": 67,
  593. },
  594. {
  595. "function": "a",
  596. "abs_path": None,
  597. "module": "org.a.b.g$a",
  598. "filename": None,
  599. "lineno": 69,
  600. "in_app": False,
  601. },
  602. {
  603. "function": "a",
  604. "abs_path": None,
  605. "module": "org.a.b.g$a",
  606. "filename": None,
  607. "lineno": 68,
  608. "in_app": True,
  609. },
  610. {
  611. "function": "init",
  612. "abs_path": None,
  613. "module": "com.android.Zygote",
  614. "filename": None,
  615. "lineno": 62,
  616. },
  617. {
  618. "function": "a",
  619. "abs_path": None,
  620. "module": "org.a.b.g$b",
  621. "filename": None,
  622. "lineno": 70,
  623. },
  624. ]
  625. },
  626. "module": "org.a.b",
  627. "type": "g$a",
  628. "value": "Attempt to invoke virtual method 'org.a.b.g$a.a' on a null object reference",
  629. }
  630. ]
  631. },
  632. "timestamp": iso_format(before_now(seconds=1)),
  633. }
  634. event = self.post_and_retrieve_event(event_data)
  635. if not self.use_relay():
  636. # We measure the number of queries after an initial post,
  637. # because there are many queries polluting the array
  638. # before the actual "processing" happens (like, auth_user)
  639. with self.assertWriteQueries(
  640. {
  641. "nodestore_node": 2,
  642. "sentry_eventuser": 1,
  643. "sentry_groupedmessage": 1,
  644. "sentry_userreport": 1,
  645. }
  646. ):
  647. self.post_and_retrieve_event(event_data)
  648. exc = event.interfaces["exception"].values[0]
  649. bt = exc.stacktrace
  650. frames = bt.frames
  651. assert exc.module == "org.slf4j.helpers"
  652. assert frames[0].in_app is True
  653. assert frames[1].in_app is False
  654. assert frames[2].in_app is True
  655. assert frames[3].in_app is False
  656. assert frames[4].in_app is True
  657. def test_resolving_inline(self):
  658. self.upload_proguard_mapping(PROGUARD_INLINE_UUID, PROGUARD_INLINE_SOURCE)
  659. event_data = {
  660. "user": {"ip_address": "31.172.207.97"},
  661. "extra": {},
  662. "project": self.project.id,
  663. "platform": "java",
  664. "debug_meta": {"images": [{"type": "proguard", "uuid": PROGUARD_INLINE_UUID}]},
  665. "exception": {
  666. "values": [
  667. {
  668. "stacktrace": {
  669. "frames": [
  670. {
  671. "function": "onClick",
  672. "abs_path": None,
  673. "module": "e.a.c.a",
  674. "filename": None,
  675. "lineno": 2,
  676. },
  677. {
  678. "function": "t",
  679. "abs_path": None,
  680. "module": "io.sentry.sample.MainActivity",
  681. "filename": "MainActivity.java",
  682. "lineno": 1,
  683. },
  684. ]
  685. },
  686. "module": "org.a.b",
  687. "type": "g$a",
  688. "value": "Oh no",
  689. }
  690. ]
  691. },
  692. "timestamp": iso_format(before_now(seconds=1)),
  693. }
  694. event = self.post_and_retrieve_event(event_data)
  695. if not self.use_relay():
  696. # We measure the number of queries after an initial post,
  697. # because there are many queries polluting the array
  698. # before the actual "processing" happens (like, auth_user)
  699. with self.assertWriteQueries(
  700. {
  701. "nodestore_node": 2,
  702. "sentry_eventuser": 1,
  703. "sentry_groupedmessage": 1,
  704. "sentry_userreport": 1,
  705. }
  706. ):
  707. self.post_and_retrieve_event(event_data)
  708. exc = event.interfaces["exception"].values[0]
  709. bt = exc.stacktrace
  710. frames = bt.frames
  711. assert len(frames) == 4
  712. assert frames[0].function == "onClick"
  713. assert frames[0].module == "io.sentry.sample.-$$Lambda$r3Avcbztes2hicEObh02jjhQqd4"
  714. assert frames[1].filename == "MainActivity.java"
  715. assert frames[1].module == "io.sentry.sample.MainActivity"
  716. assert frames[1].function == "onClickHandler"
  717. assert frames[1].lineno == 40
  718. assert frames[2].function == "foo"
  719. assert frames[2].lineno == 44
  720. assert frames[3].function == "bar"
  721. assert frames[3].lineno == 54
  722. assert frames[3].filename == "MainActivity.java"
  723. assert frames[3].module == "io.sentry.sample.MainActivity"
  724. def test_resolving_inline_with_native_frames(self):
  725. self.upload_proguard_mapping(PROGUARD_INLINE_UUID, PROGUARD_INLINE_SOURCE)
  726. event_data = {
  727. "user": {"ip_address": "31.172.207.97"},
  728. "extra": {},
  729. "project": self.project.id,
  730. "platform": "java",
  731. "debug_meta": {"images": [{"type": "proguard", "uuid": PROGUARD_INLINE_UUID}]},
  732. "exception": {
  733. "values": [
  734. {
  735. "stacktrace": {
  736. "frames": [
  737. {
  738. "function": "onClick",
  739. "abs_path": None,
  740. "module": "e.a.c.a",
  741. "filename": None,
  742. "lineno": 2,
  743. },
  744. {
  745. "function": "t",
  746. "abs_path": None,
  747. "module": "io.sentry.sample.MainActivity",
  748. "filename": "MainActivity.java",
  749. "lineno": 1,
  750. },
  751. {
  752. "abs_path": "Thread.java",
  753. "filename": "Thread.java",
  754. "function": "sleep",
  755. "lineno": 450,
  756. "lock": {
  757. "address": "0x0ddc1f22",
  758. "class_name": "Object",
  759. "package_name": "java.lang",
  760. "type:": 1,
  761. },
  762. "module": "java.lang.Thread",
  763. },
  764. {
  765. "function": "__start_thread",
  766. "package": "/apex/com.android.art/lib64/libart.so",
  767. "lineno": 196,
  768. "in_app": False,
  769. },
  770. ]
  771. },
  772. "module": "org.a.b",
  773. "type": "g$a",
  774. "value": "Oh no",
  775. }
  776. ]
  777. },
  778. "timestamp": iso_format(before_now(seconds=1)),
  779. }
  780. event = self.post_and_retrieve_event(event_data)
  781. if not self.use_relay():
  782. # We measure the number of queries after an initial post,
  783. # because there are many queries polluting the array
  784. # before the actual "processing" happens (like, auth_user)
  785. with self.assertWriteQueries(
  786. {
  787. "nodestore_node": 2,
  788. "sentry_eventuser": 1,
  789. "sentry_groupedmessage": 1,
  790. "sentry_userreport": 1,
  791. }
  792. ):
  793. self.post_and_retrieve_event(event_data)
  794. exc = event.interfaces["exception"].values[0]
  795. bt = exc.stacktrace
  796. frames = bt.frames
  797. assert len(frames) == 6
  798. assert frames[0].function == "onClick"
  799. assert frames[0].module == "io.sentry.sample.-$$Lambda$r3Avcbztes2hicEObh02jjhQqd4"
  800. assert frames[1].filename == "MainActivity.java"
  801. assert frames[1].module == "io.sentry.sample.MainActivity"
  802. assert frames[1].function == "onClickHandler"
  803. assert frames[1].lineno == 40
  804. assert frames[2].function == "foo"
  805. assert frames[2].lineno == 44
  806. assert frames[3].function == "bar"
  807. assert frames[3].lineno == 54
  808. assert frames[3].filename == "MainActivity.java"
  809. assert frames[3].module == "io.sentry.sample.MainActivity"
  810. assert frames[4].function == "sleep"
  811. assert frames[4].lineno == 450
  812. assert frames[4].filename == "Thread.java"
  813. assert frames[4].module == "java.lang.Thread"
  814. assert frames[5].function == "__start_thread"
  815. assert frames[5].package == "/apex/com.android.art/lib64/libart.so"
  816. def test_error_on_resolving(self):
  817. url = reverse(
  818. "sentry-api-0-dsym-files",
  819. kwargs={
  820. "organization_slug": self.project.organization.slug,
  821. "project_slug": self.project.slug,
  822. },
  823. )
  824. self.login_as(user=self.user)
  825. out = BytesIO()
  826. f = zipfile.ZipFile(out, "w")
  827. f.writestr("proguard/%s.txt" % PROGUARD_BUG_UUID, PROGUARD_BUG_SOURCE)
  828. f.close()
  829. response = self.client.post(
  830. url,
  831. {
  832. "file": SimpleUploadedFile(
  833. "symbols.zip", out.getvalue(), content_type="application/zip"
  834. )
  835. },
  836. format="multipart",
  837. )
  838. assert response.status_code == 201, response.content
  839. assert len(response.json()) == 1
  840. event_data = {
  841. "user": {"ip_address": "31.172.207.97"},
  842. "extra": {},
  843. "project": self.project.id,
  844. "platform": "java",
  845. "debug_meta": {"images": [{"type": "proguard", "uuid": PROGUARD_BUG_UUID}]},
  846. "exception": {
  847. "values": [
  848. {
  849. "stacktrace": {
  850. "frames": [
  851. {
  852. "function": "a",
  853. "abs_path": None,
  854. "module": "org.a.b.g$a",
  855. "filename": None,
  856. "lineno": 67,
  857. },
  858. {
  859. "function": "a",
  860. "abs_path": None,
  861. "module": "org.a.b.g$a",
  862. "filename": None,
  863. "lineno": 69,
  864. },
  865. ]
  866. },
  867. "type": "RuntimeException",
  868. "value": "Oh no",
  869. }
  870. ]
  871. },
  872. "timestamp": iso_format(before_now(seconds=1)),
  873. }
  874. event = self.post_and_retrieve_event(event_data)
  875. assert len(event.data["errors"]) == 1
  876. assert event.data["errors"][0] == {
  877. "mapping_uuid": "071207ac-b491-4a74-957c-2c94fd9594f2",
  878. "type": "proguard_missing_lineno",
  879. }
  880. def upload_jvm_bundle(self, debug_id, source_files):
  881. files = {}
  882. for source_file in source_files:
  883. files[f"files/_/_/{source_file}"] = {"url": f"~/{source_file}"}
  884. manifest = {
  885. "org": self.project.organization.slug,
  886. "project": self.project.slug,
  887. "debug_id": debug_id,
  888. "files": files,
  889. }
  890. file_like = BytesIO()
  891. with zipfile.ZipFile(file_like, "w") as zip:
  892. for source_file in source_files:
  893. zip.writestr(f"files/_/_/{source_file}", source_files[source_file])
  894. zip.writestr("manifest.json", json.dumps(manifest))
  895. file_like.seek(0)
  896. file = File.objects.create(name="bundle.zip", type="artifact.bundle")
  897. file.putfile(file_like)
  898. ProjectDebugFile.objects.create(
  899. project_id=self.project.id,
  900. debug_id=debug_id,
  901. file=file,
  902. )
  903. def test_basic_source_lookup(self):
  904. debug_id = str(uuid4())
  905. self.upload_jvm_bundle(debug_id, {"io/sentry/samples/MainActivity.jvm": JVM_SOURCE})
  906. event_data = {
  907. "user": {"ip_address": "31.172.207.97"},
  908. "extra": {},
  909. "project": self.project.id,
  910. "platform": "java",
  911. "debug_meta": {"images": [{"type": "jvm", "debug_id": debug_id}]},
  912. "exception": {
  913. "values": [
  914. {
  915. "stacktrace": {
  916. "frames": [
  917. {
  918. "function": "otherMethod",
  919. "abs_path": "OtherActivity.java",
  920. "module": "OtherActivity",
  921. "filename": "OtherActivity.java",
  922. "lineno": 100,
  923. },
  924. {
  925. "function": "differentMethod",
  926. "abs_path": "DifferentActivity",
  927. "module": "DifferentActivity",
  928. "filename": "DifferentActivity",
  929. "lineno": 200,
  930. },
  931. {
  932. "function": "onCreate",
  933. "abs_path": None,
  934. "module": "io.sentry.samples.MainActivity",
  935. "filename": None,
  936. "lineno": 11,
  937. },
  938. {
  939. "function": "whoops",
  940. "abs_path": "MainActivity.kt",
  941. "module": "io.sentry.samples.MainActivity$InnerClass",
  942. "filename": "MainActivity.kt",
  943. "lineno": 20,
  944. },
  945. {
  946. "function": "whoops2",
  947. "abs_path": None,
  948. "module": "io.sentry.samples.MainActivity$AnotherInnerClass",
  949. "filename": None,
  950. "lineno": 26,
  951. },
  952. {
  953. "function": "whoops3",
  954. "abs_path": "MainActivity.kt",
  955. "module": "io.sentry.samples.MainActivity$AdditionalInnerClass",
  956. "filename": "MainActivity.kt",
  957. "lineno": 32,
  958. },
  959. {
  960. "function": "whoops4",
  961. "abs_path": "SourceFile",
  962. "module": "io.sentry.samples.MainActivity$OneMoreInnerClass",
  963. "filename": "SourceFile",
  964. "lineno": 38,
  965. },
  966. ]
  967. },
  968. "module": "io.sentry.samples",
  969. "type": "RuntimeException",
  970. "value": "whoops",
  971. }
  972. ]
  973. },
  974. "timestamp": iso_format(before_now(seconds=1)),
  975. }
  976. event = self.post_and_retrieve_event(event_data)
  977. if not self.use_relay():
  978. # We measure the number of queries after an initial post,
  979. # because there are many queries polluting the array
  980. # before the actual "processing" happens (like, auth_user)
  981. with self.assertWriteQueries(
  982. {
  983. "nodestore_node": 2,
  984. "sentry_eventuser": 1,
  985. "sentry_groupedmessage": 1,
  986. "sentry_userreport": 1,
  987. }
  988. ):
  989. self.post_and_retrieve_event(event_data)
  990. exc = event.interfaces["exception"].values[0]
  991. bt = exc.stacktrace
  992. frames = bt.frames
  993. assert exc.type == "RuntimeException"
  994. assert exc.value == "whoops"
  995. assert exc.module == "io.sentry.samples"
  996. assert frames[0].function == "otherMethod"
  997. assert frames[0].module == "OtherActivity"
  998. assert frames[0].lineno == 100
  999. assert frames[0].context_line is None
  1000. assert frames[0].pre_context is None
  1001. assert frames[0].post_context is None
  1002. assert frames[1].function == "differentMethod"
  1003. assert frames[1].module == "DifferentActivity"
  1004. assert frames[1].lineno == 200
  1005. assert frames[1].context_line is None
  1006. assert frames[1].pre_context is None
  1007. assert frames[1].post_context is None
  1008. assert frames[2].function == "onCreate"
  1009. assert frames[2].module == "io.sentry.samples.MainActivity"
  1010. assert frames[2].lineno == 11
  1011. assert frames[2].context_line == " InnerClass().whoops()"
  1012. assert frames[2].pre_context == [
  1013. "",
  1014. "class MainActivity : ComponentActivity() {",
  1015. " override fun onCreate(savedInstanceState: Bundle?) {",
  1016. " super.onCreate(savedInstanceState)",
  1017. " setContentView(R.layout.activity_main)",
  1018. ]
  1019. assert frames[2].post_context == [
  1020. "",
  1021. " val list = findViewById<RecyclerView>(R.id.list)",
  1022. " list.layoutManager = LinearLayoutManager(this)",
  1023. " list.adapter = TrackAdapter()",
  1024. " }",
  1025. ]
  1026. assert frames[3].function == "whoops"
  1027. assert frames[3].module == "io.sentry.samples.MainActivity$InnerClass"
  1028. assert frames[3].lineno == 20
  1029. assert frames[3].context_line == " AnotherInnerClass().whoops2()"
  1030. assert frames[3].pre_context == [
  1031. " list.adapter = TrackAdapter()",
  1032. " }",
  1033. "",
  1034. " class InnerClass {",
  1035. " fun whoops() {",
  1036. ]
  1037. assert frames[3].post_context == [
  1038. " }",
  1039. " }",
  1040. "",
  1041. " class AnotherInnerClass {",
  1042. " fun whoops2() {",
  1043. ]
  1044. assert frames[4].function == "whoops2"
  1045. assert frames[4].module == "io.sentry.samples.MainActivity$AnotherInnerClass"
  1046. assert frames[4].lineno == 26
  1047. assert frames[4].context_line == " AdditionalInnerClass().whoops3()"
  1048. assert frames[4].pre_context == [
  1049. " }",
  1050. " }",
  1051. "",
  1052. " class AnotherInnerClass {",
  1053. " fun whoops2() {",
  1054. ]
  1055. assert frames[4].post_context == [
  1056. " }",
  1057. " }",
  1058. "",
  1059. " class AdditionalInnerClass {",
  1060. " fun whoops3() {",
  1061. ]
  1062. assert frames[5].function == "whoops3"
  1063. assert frames[5].module == "io.sentry.samples.MainActivity$AdditionalInnerClass"
  1064. assert frames[5].lineno == 32
  1065. assert frames[5].context_line == " OneMoreInnerClass().whoops4()"
  1066. assert frames[5].pre_context == [
  1067. " }",
  1068. " }",
  1069. "",
  1070. " class AdditionalInnerClass {",
  1071. " fun whoops3() {",
  1072. ]
  1073. assert frames[5].post_context == [
  1074. " }",
  1075. " }",
  1076. "",
  1077. " class OneMoreInnerClass {",
  1078. " fun whoops4() {",
  1079. ]
  1080. assert frames[6].function == "whoops4"
  1081. assert frames[6].module == "io.sentry.samples.MainActivity$OneMoreInnerClass"
  1082. assert frames[6].lineno == 38
  1083. assert frames[6].context_line == ' throw RuntimeException("whoops")'
  1084. assert frames[6].pre_context == [
  1085. " }",
  1086. " }",
  1087. "",
  1088. " class OneMoreInnerClass {",
  1089. " fun whoops4() {",
  1090. ]
  1091. assert frames[6].post_context == [" }", " }", "}", ""]
  1092. def test_source_lookup_with_proguard(self):
  1093. self.upload_proguard_mapping(PROGUARD_SOURCE_LOOKUP_UUID, PROGUARD_SOURCE_LOOKUP_SOURCE)
  1094. debug_id1 = str(uuid4())
  1095. self.upload_jvm_bundle(
  1096. debug_id1,
  1097. {
  1098. "io/sentry/samples/instrumentation/ui/EditActivity.jvm": EDIT_ACTIVITY_SOURCE,
  1099. },
  1100. )
  1101. debug_id2 = str(uuid4())
  1102. self.upload_jvm_bundle(
  1103. debug_id2,
  1104. {
  1105. "io/sentry/samples/instrumentation/ui/SomeService.jvm": SOME_SERVICE_SOURCE,
  1106. },
  1107. )
  1108. event_data = {
  1109. "user": {"ip_address": "31.172.207.97"},
  1110. "extra": {},
  1111. "project": self.project.id,
  1112. "platform": "java",
  1113. "debug_meta": {
  1114. "images": [
  1115. {
  1116. "type": "jvm",
  1117. "debug_id": debug_id1,
  1118. },
  1119. {
  1120. "type": "jvm",
  1121. "debug_id": debug_id2,
  1122. },
  1123. {
  1124. "type": "jvm",
  1125. "debug_id": str(uuid4()),
  1126. }, # does not exist
  1127. {"type": "proguard", "uuid": PROGUARD_SOURCE_LOOKUP_UUID},
  1128. {"type": "proguard", "uuid": str(uuid4())}, # does not exist
  1129. ]
  1130. },
  1131. "exception": {
  1132. "values": [
  1133. {
  1134. "type": "RuntimeException",
  1135. "value": "thrown on purpose to test ProGuard Android source context",
  1136. "module": "java.lang",
  1137. "thread_id": 1,
  1138. "stacktrace": {
  1139. "frames": [
  1140. {
  1141. "filename": "ZygoteInit.java",
  1142. "function": "main",
  1143. "module": "com.android.internal.os.ZygoteInit",
  1144. "lineno": 698,
  1145. "native": False,
  1146. },
  1147. {
  1148. "filename": "ZygoteInit.java",
  1149. "function": "run",
  1150. "module": "com.android.internal.os.ZygoteInit$MethodAndArgsCaller",
  1151. "lineno": 903,
  1152. "native": False,
  1153. },
  1154. {
  1155. "filename": "Method.java",
  1156. "function": "invoke",
  1157. "module": "java.lang.reflect.Method",
  1158. "lineno": 372,
  1159. "native": False,
  1160. },
  1161. {
  1162. "filename": "Method.java",
  1163. "function": "invoke",
  1164. "module": "java.lang.reflect.Method",
  1165. "native": True,
  1166. },
  1167. {
  1168. "filename": "ActivityThread.java",
  1169. "function": "main",
  1170. "module": "android.app.ActivityThread",
  1171. "lineno": 5254,
  1172. "native": False,
  1173. },
  1174. {
  1175. "filename": "Looper.java",
  1176. "function": "loop",
  1177. "module": "android.os.Looper",
  1178. "lineno": 135,
  1179. "native": False,
  1180. },
  1181. {
  1182. "filename": "Handler.java",
  1183. "function": "dispatchMessage",
  1184. "module": "android.os.Handler",
  1185. "lineno": 95,
  1186. "native": False,
  1187. },
  1188. {
  1189. "filename": "Handler.java",
  1190. "function": "handleCallback",
  1191. "module": "android.os.Handler",
  1192. "lineno": 739,
  1193. "native": False,
  1194. },
  1195. {
  1196. "filename": "View.java",
  1197. "function": "run",
  1198. "module": "android.view.View$PerformClick",
  1199. "lineno": 19866,
  1200. "native": False,
  1201. },
  1202. {
  1203. "filename": "View.java",
  1204. "function": "performClick",
  1205. "module": "android.view.View",
  1206. "lineno": 4780,
  1207. "native": False,
  1208. },
  1209. {
  1210. "filename": "ActionMenuItemView.java",
  1211. "function": "onClick",
  1212. "module": "androidx.appcompat.view.menu.ActionMenuItemView",
  1213. "lineno": 7,
  1214. "native": False,
  1215. },
  1216. {
  1217. "filename": "ActionMenuView.java",
  1218. "function": "invokeItem",
  1219. "module": "androidx.appcompat.widget.ActionMenuView",
  1220. "lineno": 4,
  1221. "native": False,
  1222. },
  1223. {
  1224. "filename": "MenuBuilder.java",
  1225. "function": "performItemAction",
  1226. "module": "androidx.appcompat.view.menu.MenuBuilder",
  1227. "lineno": 1,
  1228. "native": False,
  1229. },
  1230. {
  1231. "filename": "MenuBuilder.java",
  1232. "function": "performItemAction",
  1233. "module": "androidx.appcompat.view.menu.MenuBuilder",
  1234. "lineno": 4,
  1235. "native": False,
  1236. },
  1237. {
  1238. "filename": "MenuItemImpl.java",
  1239. "function": "invoke",
  1240. "module": "androidx.appcompat.view.menu.MenuItemImpl",
  1241. "lineno": 15,
  1242. "native": False,
  1243. },
  1244. {
  1245. "filename": "MenuBuilder.java",
  1246. "function": "dispatchMenuItemSelected",
  1247. "module": "androidx.appcompat.view.menu.MenuBuilder",
  1248. "lineno": 5,
  1249. "native": False,
  1250. },
  1251. {
  1252. "filename": "ActionMenuView.java",
  1253. "function": "onMenuItemSelected",
  1254. "module": "androidx.appcompat.widget.ActionMenuView$MenuBuilderCallback",
  1255. "lineno": 7,
  1256. "native": False,
  1257. },
  1258. {
  1259. "filename": "Toolbar.java",
  1260. "function": "onMenuItemClick",
  1261. "module": "androidx.appcompat.widget.Toolbar$1",
  1262. "lineno": 7,
  1263. "native": False,
  1264. },
  1265. {
  1266. "filename": "R8$$SyntheticClass",
  1267. "function": "onMenuItemClick",
  1268. "module": "io.sentry.samples.instrumentation.ui.g",
  1269. "lineno": 40,
  1270. "in_app": True,
  1271. "native": False,
  1272. },
  1273. ]
  1274. },
  1275. }
  1276. ]
  1277. },
  1278. "timestamp": iso_format(before_now(seconds=1)),
  1279. }
  1280. event = self.post_and_retrieve_event(event_data)
  1281. if not self.use_relay():
  1282. # We measure the number of queries after an initial post,
  1283. # because there are many queries polluting the array
  1284. # before the actual "processing" happens (like, auth_user)
  1285. with self.assertWriteQueries(
  1286. {
  1287. "nodestore_node": 2,
  1288. "sentry_eventuser": 1,
  1289. "sentry_groupedmessage": 1,
  1290. "sentry_userreport": 1,
  1291. }
  1292. ):
  1293. self.post_and_retrieve_event(event_data)
  1294. exc = event.interfaces["exception"].values[0]
  1295. bt = exc.stacktrace
  1296. frames = bt.frames
  1297. assert exc.type == "RuntimeException"
  1298. assert exc.value == "thrown on purpose to test ProGuard Android source context"
  1299. assert exc.module == "java.lang"
  1300. assert frames[18].function == "onMenuItemClick"
  1301. assert (
  1302. frames[18].module
  1303. == "io.sentry.samples.instrumentation.ui.EditActivity$$InternalSyntheticLambda$1$ebaa538726b99bb77e0f5e7c86443911af17d6e5be2b8771952ae0caa4ff2ac7$0"
  1304. )
  1305. assert frames[18].lineno == 0
  1306. assert frames[18].context_line is None
  1307. assert frames[18].pre_context is None
  1308. assert frames[18].post_context is None
  1309. assert frames[19].function == "onCreate$lambda-1"
  1310. assert frames[19].module == "io.sentry.samples.instrumentation.ui.EditActivity"
  1311. assert frames[19].lineno == 37
  1312. assert frames[19].context_line == " SomeService().helloThere()"
  1313. assert frames[19].pre_context == [
  1314. " }",
  1315. "",
  1316. " findViewById<Toolbar>(R.id.toolbar).setOnMenuItemClickListener {",
  1317. " if (it.itemId == R.id.action_save) {",
  1318. " try {",
  1319. ]
  1320. assert frames[19].post_context == [
  1321. " } catch (e: Exception) {",
  1322. " Sentry.captureException(e)",
  1323. " }",
  1324. "",
  1325. " val transaction = Sentry.startTransaction(",
  1326. ]
  1327. assert frames[20].function == "helloThere"
  1328. assert frames[20].module == "io.sentry.samples.instrumentation.ui.SomeService"
  1329. assert frames[20].lineno == 5
  1330. assert frames[20].context_line == " InnerClassOfSomeService().helloInner()"
  1331. assert frames[20].pre_context == [
  1332. "package io.sentry.samples.instrumentation.ui",
  1333. "",
  1334. "class SomeService {",
  1335. " fun helloThere() {",
  1336. ]
  1337. assert frames[20].post_context == [
  1338. " }",
  1339. "",
  1340. " class InnerClassOfSomeService {",
  1341. " fun helloInner() {",
  1342. " AnotherClassInSameFile().helloOther()",
  1343. ]
  1344. assert frames[21].function == "helloInner"
  1345. assert (
  1346. frames[21].module
  1347. == "io.sentry.samples.instrumentation.ui.SomeService$InnerClassOfSomeService"
  1348. )
  1349. assert frames[21].lineno == 10
  1350. assert frames[21].context_line == " AnotherClassInSameFile().helloOther()"
  1351. assert frames[21].pre_context == [
  1352. " InnerClassOfSomeService().helloInner()",
  1353. " }",
  1354. "",
  1355. " class InnerClassOfSomeService {",
  1356. " fun helloInner() {",
  1357. ]
  1358. assert frames[21].post_context == [
  1359. " }",
  1360. " }",
  1361. "}",
  1362. "",
  1363. "class AnotherClassInSameFile {",
  1364. ]
  1365. assert frames[22].function == "helloOther"
  1366. assert frames[22].module == "io.sentry.samples.instrumentation.ui.AnotherClassInSameFile"
  1367. assert frames[22].lineno == 17
  1368. assert frames[22].context_line is None
  1369. assert frames[22].pre_context is None
  1370. assert frames[22].post_context is None
  1371. assert frames[23].function == "otherFun"
  1372. assert frames[23].module == "io.sentry.samples.instrumentation.ui.AnotherClassInSameFile"
  1373. assert frames[23].lineno == 21
  1374. assert frames[23].context_line is None
  1375. assert frames[23].pre_context is None
  1376. assert frames[23].post_context is None
  1377. assert frames[24].function == "helloOtherInner"
  1378. assert (
  1379. frames[24].module
  1380. == "io.sentry.samples.instrumentation.ui.AnotherClassInSameFile$AnotherInnerClass"
  1381. )
  1382. assert frames[24].lineno == 26
  1383. assert frames[24].context_line is None
  1384. assert frames[24].pre_context is None
  1385. assert frames[24].post_context is None