test_plugin.py 82 KB

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