@@ -39,6 +39,7 @@ import java.util.concurrent.atomic.AtomicReference
3939import kotlin.test.BeforeTest
4040import kotlin.test.Test
4141import kotlin.test.assertEquals
42+ import kotlin.test.assertNotEquals
4243import kotlin.test.assertNotNull
4344import kotlin.test.assertNull
4445import kotlin.test.assertTrue
@@ -84,7 +85,7 @@ class InternalSentrySdkTest {
8485 capturedEnvelopes.clear()
8586 }
8687
87- fun captureEnvelopeWithEvent (event : SentryEvent = SentryEvent ()) {
88+ fun captureEnvelopeWithEvent (event : SentryEvent = SentryEvent (), maybeStartNewSession : Boolean = false ) {
8889 // create an envelope with session data
8990 val options = Sentry .getCurrentHub().options
9091 val eventId = SentryId ()
@@ -103,7 +104,24 @@ class InternalSentrySdkTest {
103104 options.serializer.serialize(envelope, outputStream)
104105 val data = outputStream.toByteArray()
105106
106- InternalSentrySdk .captureEnvelope(data)
107+ InternalSentrySdk .captureEnvelope(data, maybeStartNewSession)
108+ }
109+
110+ fun createSentryEventWithUnhandledException (): SentryEvent {
111+ return SentryEvent (RuntimeException ()).apply {
112+ val mechanism = Mechanism ()
113+ mechanism.isHandled = false
114+
115+ val factory = SentryExceptionFactory (mock())
116+ val sentryExceptions = factory.getSentryExceptions(
117+ ExceptionMechanismException (
118+ mechanism,
119+ Throwable (),
120+ Thread ()
121+ )
122+ )
123+ exceptions = sentryExceptions
124+ }
107125 }
108126
109127 fun mockFinishedAppStart () {
@@ -313,7 +331,7 @@ class InternalSentrySdkTest {
313331
314332 @Test
315333 fun `captureEnvelope fails if payload is invalid` () {
316- assertNull(InternalSentrySdk .captureEnvelope(ByteArray (8 )))
334+ assertNull(InternalSentrySdk .captureEnvelope(ByteArray (8 ), false ))
317335 }
318336
319337 @Test
@@ -337,27 +355,12 @@ class InternalSentrySdkTest {
337355 }
338356
339357 @Test
340- fun `captureEnvelope correctly enriches the envelope with session data` () {
358+ fun `captureEnvelope correctly enriches the envelope with session data and does not start new session ` () {
341359 val fixture = Fixture ()
342360 fixture.init (context)
343361
344362 // when capture envelope is called with an crashed event
345- fixture.captureEnvelopeWithEvent(
346- SentryEvent (RuntimeException ()).apply {
347- val mechanism = Mechanism ()
348- mechanism.isHandled = false
349-
350- val factory = SentryExceptionFactory (mock())
351- val sentryExceptions = factory.getSentryExceptions(
352- ExceptionMechanismException (
353- mechanism,
354- Throwable (),
355- Thread ()
356- )
357- )
358- exceptions = sentryExceptions
359- }
360- )
363+ fixture.captureEnvelopeWithEvent(fixture.createSentryEventWithUnhandledException())
361364
362365 val capturedEnvelope = fixture.capturedEnvelopes.first()
363366 val capturedEnvelopeItems = capturedEnvelope.items.toList()
@@ -380,6 +383,51 @@ class InternalSentrySdkTest {
380383 scopeRef.set(scope)
381384 }
382385 assertEquals(Session .State .Crashed , scopeRef.get().session!! .status)
386+ assertEquals(capturedSession.sessionId, scopeRef.get().session!! .sessionId)
387+ }
388+
389+ @Test
390+ fun `captureEnvelope starts new session when enabled` () {
391+ val fixture = Fixture ()
392+ fixture.init (context)
393+
394+ // when capture envelope is called with an crashed event
395+ fixture.captureEnvelopeWithEvent(fixture.createSentryEventWithUnhandledException(), true )
396+
397+ val scopeRef = AtomicReference <IScope >()
398+ Sentry .configureScope { scope ->
399+ scopeRef.set(scope)
400+ }
401+
402+ // first envelope is the new session start
403+ val capturedStartSessionEnvelope = fixture.capturedEnvelopes.first()
404+ val capturedNewSessionStart = fixture.options.serializer.deserialize(
405+ InputStreamReader (ByteArrayInputStream (capturedStartSessionEnvelope.items.toList()[0 ].data)),
406+ Session ::class .java
407+ )!!
408+ assertEquals(capturedNewSessionStart.sessionId, scopeRef.get().session!! .sessionId)
409+ assertEquals(Session .State .Ok , capturedNewSessionStart.status)
410+
411+ val capturedEnvelope = fixture.capturedEnvelopes.last()
412+ val capturedEnvelopeItems = capturedEnvelope.items.toList()
413+
414+ // there should be two envelopes session start and captured crash
415+ assertEquals(2 , fixture.capturedEnvelopes.size)
416+
417+ // then it should contain the original event + session
418+ assertEquals(2 , capturedEnvelopeItems.size)
419+ assertEquals(SentryItemType .Event , capturedEnvelopeItems[0 ].header.type)
420+ assertEquals(SentryItemType .Session , capturedEnvelopeItems[1 ].header.type)
421+
422+ // and then the sent session should be marked as crashed
423+ val capturedSession = fixture.options.serializer.deserialize(
424+ InputStreamReader (ByteArrayInputStream (capturedEnvelopeItems[1 ].data)),
425+ Session ::class .java
426+ )!!
427+ assertEquals(Session .State .Crashed , capturedSession.status)
428+
429+ // and the local session should be a new session
430+ assertNotEquals(capturedSession.sessionId, scopeRef.get().session!! .sessionId)
383431 }
384432
385433 @Test
0 commit comments