From 5c78a824ee55ed64494f6ba9b9a9080474ddb291 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 9 Sep 2026 12:29:29 +0100 Subject: [PATCH 1/2] test(android): stabilize InternalSentrySdk session tests --- .../io/sentry/android/core/InternalSentrySdkTest.kt | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt index 6fbc7b1ebe7..30ccc6fe5d1 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt @@ -30,6 +30,7 @@ import io.sentry.protocol.Contexts import io.sentry.protocol.Mechanism import io.sentry.protocol.SentryId import io.sentry.protocol.User +import io.sentry.test.ImmediateExecutorService import io.sentry.test.createTestScopes import io.sentry.transport.ITransport import io.sentry.transport.RateLimiter @@ -38,7 +39,6 @@ import java.io.ByteArrayOutputStream import java.io.InputStreamReader import java.util.concurrent.atomic.AtomicReference import kotlin.test.BeforeTest -import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotEquals @@ -62,6 +62,8 @@ class InternalSentrySdkTest { initForTest(context) { options -> this@Fixture.options = options options.dsn = "https://key@host/proj" + // Finish startup session rotation before tests persist and read the current session. + options.executorService = ImmediateExecutorService() options.setTransportFactory { _, _ -> object : ITransport { override fun close(isRestarting: Boolean) { @@ -613,14 +615,6 @@ class InternalSentrySdkTest { assertThat(activeSession.get().sessionId).isNotEqualTo(oldSid) } - // Flaky: intermittently fails with FileNotFoundException reading session.json at the - // `sessionFile.reader()` call below, i.e. persistCurrentSession() did not leave a session file - // on disk by the time this test reads it back. Seen across unrelated PRs, e.g.: - // https://scans.gradle.com/s/55fnn6xhtfyfq/tests/task/:sentry-android-core:testReleaseUnitTest/details/io.sentry.android.core.InternalSentrySdkTest/updateSessionForDroppedEventNonTerminating%20flags%20an%20unhandled%20error%20without%20sending%20an%20envelope?top-execution=1 - // https://scans.gradle.com/s/ojzzz4yxag7rw/tests/task/:sentry-android-core:testReleaseUnitTest/details/io.sentry.android.core.InternalSentrySdkTest/updateSessionForDroppedEventNonTerminating%20flags%20an%20unhandled%20error%20without%20sending%20an%20envelope?top-execution=1 - // Disabling until root-caused; see https://github.com/getsentry/sentry-java/pull/5990 for the - // code under test. - @Ignore("Flaky: intermittently fails to find the persisted session.json, needs root-causing") @Test fun `updateSessionForDroppedEventNonTerminating flags an unhandled error without sending an envelope`() { val fixture = Fixture() From 13c17fac5700048893de0dd4af5f7e90e47c95d4 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 9 Sep 2026 12:34:04 +0100 Subject: [PATCH 2/2] test(android): configure session test executor per test --- .../io/sentry/android/core/InternalSentrySdkTest.kt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt index 30ccc6fe5d1..e4449f71548 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt @@ -9,6 +9,7 @@ import com.google.common.truth.Truth.assertThat import io.sentry.Breadcrumb import io.sentry.Hint import io.sentry.IScope +import io.sentry.ISentryExecutorService import io.sentry.Scope import io.sentry.ScopeType import io.sentry.Sentry @@ -58,12 +59,12 @@ class InternalSentrySdkTest { val capturedEnvelopes = mutableListOf() lateinit var options: SentryOptions - fun init(context: Context) { + fun init(context: Context, executorService: ISentryExecutorService? = null) { initForTest(context) { options -> this@Fixture.options = options options.dsn = "https://key@host/proj" - // Finish startup session rotation before tests persist and read the current session. - options.executorService = ImmediateExecutorService() + // Session persistence tests can finish startup rotation before writing session.json. + executorService?.let { options.executorService = it } options.setTransportFactory { _, _ -> object : ITransport { override fun close(isRestarting: Boolean) { @@ -486,7 +487,7 @@ class InternalSentrySdkTest { @Test fun `captureEnvelopeNonTerminating keeps the session Ok and flags the unhandled error`() { val fixture = Fixture() - fixture.init(context) + fixture.init(context, executorService = ImmediateExecutorService()) val originalSid = AtomicReference() Sentry.configureScope { scope -> originalSid.set(scope.session!!.sessionId) } @@ -618,7 +619,7 @@ class InternalSentrySdkTest { @Test fun `updateSessionForDroppedEventNonTerminating flags an unhandled error without sending an envelope`() { val fixture = Fixture() - fixture.init(context) + fixture.init(context, executorService = ImmediateExecutorService()) val originalSid = AtomicReference() Sentry.configureScope { scope -> originalSid.set(scope.session!!.sessionId) } @@ -647,7 +648,7 @@ class InternalSentrySdkTest { @Test fun `updateSessionForDroppedEventNonTerminating increments errors for a handled error without sending an envelope`() { val fixture = Fixture() - fixture.init(context) + fixture.init(context, executorService = ImmediateExecutorService()) val originalSid = AtomicReference() Sentry.configureScope { scope -> originalSid.set(scope.session!!.sessionId) }