@@ -4,7 +4,11 @@ import io.sentry.Session.State.Crashed
44import io.sentry.cache.EnvelopeCache
55import java.io.File
66import java.util.Date
7+ import kotlin.test.AfterTest
8+ import kotlin.test.BeforeTest
79import kotlin.test.assertFalse
10+ import kotlin.test.assertNull
11+ import kotlin.test.assertTrue
812import org.junit.Rule
913import org.junit.Test
1014import org.junit.rules.TemporaryFolder
@@ -17,6 +21,16 @@ import org.mockito.kotlin.verify
1721class PreviousSessionFinalizerTest {
1822 @get:Rule val tmpDir = TemporaryFolder ()
1923
24+ @BeforeTest
25+ fun `set up` () {
26+ SentryCrashLastRunState .getInstance().reset()
27+ }
28+
29+ @AfterTest
30+ fun `tear down` () {
31+ SentryCrashLastRunState .getInstance().reset()
32+ }
33+
2034 class Fixture {
2135 val options = SentryOptions ()
2236 val scopes = mock<IScopes >()
@@ -205,4 +219,62 @@ class PreviousSessionFinalizerTest {
205219 )
206220 verify(fixture.scopes, never()).captureEnvelope(any())
207221 }
222+
223+ @Test
224+ fun `when previous session is already crashed, sets crashedLastRun to true` () {
225+ // Create a session that is already in Crashed state (simulating tombstone integration)
226+ val crashedSession =
227+ Session (null , null , null , " io.sentry.sample@1.0" ).apply { update(Crashed , null , true ) }
228+
229+ val finalizer = fixture.getSut(tmpDir, session = crashedSession)
230+
231+ // crashedLastRun should not be set before running the finalizer
232+ assertNull(SentryCrashLastRunState .getInstance().isCrashedLastRun(null , false ))
233+
234+ finalizer.run ()
235+
236+ // crashedLastRun should be set to true after running the finalizer
237+ assertTrue(SentryCrashLastRunState .getInstance().isCrashedLastRun(null , false )!! )
238+ }
239+
240+ @Test
241+ fun `when native crash marker exists but session is not crashed, does not set crashedLastRun` () {
242+ // Session is not crashed, but native crash marker exists
243+ val finalizer =
244+ fixture.getSut(
245+ tmpDir,
246+ session = Session (null , null , null , " io.sentry.sample@1.0" ),
247+ nativeCrashTimestamp = Date (2023 , 10 , 1 ),
248+ )
249+
250+ // crashedLastRun should not be set before running the finalizer
251+ assertNull(SentryCrashLastRunState .getInstance().isCrashedLastRun(null , false ))
252+
253+ finalizer.run ()
254+
255+ // crashedLastRun should NOT be set by PreviousSessionFinalizer for native crash marker case
256+ // (it's handled by EnvelopeCache at session start instead)
257+ assertNull(SentryCrashLastRunState .getInstance().isCrashedLastRun(null , false ))
258+ }
259+
260+ @Test
261+ fun `when previous session is already crashed and native crash marker exists, sets crashedLastRun and deletes marker` () {
262+ // Session is already crashed (tombstone case) AND native crash marker exists
263+ val crashedSession =
264+ Session (null , null , null , " io.sentry.sample@1.0" ).apply { update(Crashed , null , true ) }
265+
266+ val finalizer =
267+ fixture.getSut(tmpDir, session = crashedSession, nativeCrashTimestamp = Date (2023 , 10 , 1 ))
268+
269+ val nativeCrashMarker =
270+ File (fixture.options.cacheDirPath!! , EnvelopeCache .NATIVE_CRASH_MARKER_FILE )
271+ assertTrue(nativeCrashMarker.exists())
272+
273+ finalizer.run ()
274+
275+ // crashedLastRun should be set to true
276+ assertTrue(SentryCrashLastRunState .getInstance().isCrashedLastRun(null , false )!! )
277+ // Native crash marker should be deleted
278+ assertFalse(nativeCrashMarker.exists())
279+ }
208280}
0 commit comments