test_plugin.py 80 KB

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